IE系列直到IE9才支持DOMContentLoaded事件,对于IE8及其之前版本,如果html内没有框架,则可以采用document.documentELement.doScroll来判断
是否构建好DOM树;如果html内有框架,则利用document的onreadystatechange事件判断当前DOM树是否构建完毕(框架html内容(只是html文件)加载之后DOM树构建完毕)。
所以可以采用这种方式:
/** * 实现DomContentLoaded的兼容性 * @param callback */ var onDomContentLoaded = function(callback){ var onlyOnce = true; var onReady = function(callback){ if(onlyOnce){ onlyOnce = false; onDomContentLoaded.isDomReady = true; try{ callback(); }catch(e){ throw(new Error('DOM Ready callback occurs an error!')) } } return; } if(S.browser.isIe && !('HTMLElement' in window)){ // lt IE9 if(self.top === self){ function s(){ try{ document.documentElement.doScroll('left'); onReady(callback); return; }catch(e){ setTimeout(s,50); } } s(); }else{ //包含框架 document.attachEvent('onreadystatechange',function(){ if(document.readyState === 'complete'){ onReady(callback); document.detachEvent('onreadystatechange',arguments.callee); } }); } document.onload = function(){ onReady(callback); document.onload = null; }; }else{ document.addEventListener('DOMContentLoaded',function(){ onReady(callback); document.removeEventListener('DOMContentLoaded',arguments.callee); },false); document.onload = function(){ onReady(callback); document.onload = null; }; } };
另外,John Resig也在《精通javascript》提出了一种方法来判断DOM是否构建完毕,那就是不断轮训判断
if(document && document.getElementById && document.getElementsByTagName && document.body)是否为true,若为true,则
DOM构建完毕。
最后,给出David Flanagan所给出的whenReady函数,很有技巧性:
/* * Pass a function to whenReady() and it will be invoked (as a method of the * document) when the document is parsed and ready for manipulation. Registered * functions are triggered by the first DOMContentLoaded, readystatechange, or * load event that occurs. Once the document is ready and all functions have * been invoked, any functions passed to whenReady() will be invoked * immediately. */ var whenReady = (function() { // This function returns the whenReady() function var funcs = []; // The functions to run when we get an event var ready = false; // Switches to true when the handler is triggered // The event handler invoked when the document becomes ready function handler(e) { // If we've already run once, just return if (ready) return; // If this was a readystatechange event where the state changed to // something other than "complete", then we're not ready yet if (e.type === "readystatechange" && document.readyState !== "complete") return; // Run all registered functions. // Note that we look up funcs.length each time, in case calling // one of these functions causes more functions to be registered. for(var i = 0; i < funcs.length; i++) funcs[i].call(document); // Now set the ready flag to true and forget the functions ready = true; funcs = null; } // Register the handler for any event we might receive if (document.addEventListener) { document.addEventListener("DOMContentLoaded", handler, false); document.addEventListener("readystatechange", handler, false); window.addEventListener("load", handler, false); } else if (document.attachEvent) { document.attachEvent("onreadystatechange", handler); window.attachEvent("onload", handler); } // Return the whenReady function return function whenReady(f) { if (ready) f.call(document); // If already ready, just run it else funcs.push(f); // Otherwise, queue it for later. } }());