一个通用onReady函数的实现
2014-08-28 23:55 尔 阅读(507) 评论(0) 收藏 举报define([], function(){ function onReady(fn) { var DOC = document, html = DOC.documentElement, W3C = document.dispatchEvent; //FF以前是没有readyState属性的 //判断body是否存在来决定DOM文档是否加载完毕 if (!DOC.readyState) { var readyState = DOC.readyState = DOC.body ? "complete" : "loading"; } //如果页面已经完全载入完毕直接执行回调函数 if (DOC.readyState === "complete") { setTimeout(fn); //现代游览器和IE>=IE9 } else if (W3C) { DOC.addEventListener('DOMContentLoaded', function(){ if (readyState) { DOC.readyState = 'complete'; } fn(); }, false); } else { ieReady(fn); } } function ieReady(fn) { try { //处理iframe中的页面在IE下无法通过doScroll判断DOM知否加载完毕 if (self !== top && self.document.readyState !== 'complete') { setTimeout(function(){ ieReady.call(window, fn) }) } else if (self !== top && self.document.readyState === 'complete') { arguments[0](); } else { document.documentElement.doScroll('left'); arguments[0](); } } catch (e) { setTimeout(function(){ ieReady.call(window, fn) }) } }; AS.extend({ 'onReady': onReady }); return onReady; })
修正一个重大bug,ready函数是不能在AMD中定义从而异步加载的,因为DOMContentLoaded监听的触发时机是在DOM和JS.CSS加载执行完毕后,但有一个例外就是JS如果是动态加载进来的,DOMContentLoaded不会等待这个异步加载的js,所以如果将绑定DOMContentLoaded事件的函数写在动态加载的js中,有一个可能就是Dom已经加载完毕但动态加载的js中的为DOMContentLoaded绑定监听的代码还没有执行,所以很有可能你为DOMContentLoaded绑定的监听不会执行.