domReady的兼容性实现方法
一、为何要实现domReay方法?
举例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>domready</title> <script src="domready.js"></script> <script> document.getElementById('p01').style.color='#ff0000'; //抛出错误 TypeError: document.getElementById(...) is null </script> </head> <body> <p id="p01">javascript中domready的实现方法</p> </body> </html>
我们需要给一些元素的事件绑定处理函数。但问题是,如果那个元素还没有加载到页面上,但是绑定事件已经执行完了,是没有效果的,如上所示。
平时我们都是如此做:
<script> window.onload=function(){ document.getElementById('p01').style.color='#ff0000'; } </script>
当 onload
事件触发时,需要等待页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成。
当 DOMContentLoaded
事件触发时,仅当DOM加载完成,不包括样式表,图片,flash。
这两个事件大致就是用来避免这样一种情况,将绑定的函数放在这两个事件的回调中,保证能在页面的某些元素加载完毕之后再绑定事件的函数。
当然DOMContentLoaded机制更加合理,因为我们可以容忍图片,flash延迟加载,却不可以容忍看见内容后页面不可交互。
二、domReady实现
function domReady(fn){ //现代浏览器支持方法 if(document.addEventListener){ document.addEventListener('DOMContentLoaded', fn , false); }else { IEContentLoaded(fn); } //IE下模拟DOMContentLoaded function IEContentLoaded(fn){ var d = window.document; var flag = false; //只执行一次用户的回调函数init() var init = function () { if(!flag){ flag = true; fn(); } }; //自执行匿名函数 (function () { try { // DOM树未创建之前调用doScroll会抛出错误 d.documentElement.doScroll('left'); } catch(e) { // 延迟再执行一次 setTimeout(arguments.callee, 50); return; } //没有错误就表示DOM树创建完毕,然后立即执行用户回调 init(); })(); //监听document的加载状态 d.onreadystatechange = function () { //如果是在domready之后绑定的函数,就立马执行 if(d.readyState == 'complete'){ d.onreadystatechange = null; init(); } } } }
HTML代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>domready</title> <script src="domready.js"></script> <script> domReady(function () { document.getElementById('p01').style.color='#ff0000'; }) </script> </head> <body> <p id="p01">javascript中domready的实现方法</p> </body> </html>