DOMContentLoaded 和 window.onload 的辨别
当页面完整加载终了后会触发 window.onload 事宜,我们晓得能够应用 window.onload 事宜来触发并实行须要页面完整加载终了后才实行的 javascript 剧本,然则假如页面包括许多款式文件、图片文件、子框架页面(iframe)的话,onload 事宜也会被响应延晚到这些文件加载完成才实行,有时刻并非我们所须要的,比方我们想晓得页面从接收终了到 dom 树剖析完成所须要的时刻,那末 onload 事宜则不合适了。
这个时刻 DOMContentLoaded 就进场了,它定义为: 当页面文档加载并剖析终了今后会立时动身 DOMContentLoaded 事宜,而不会守候款式文件、图片文件和子框架页面的加载。
示例
<script>
document.addEventListener("DOMContentLoaded", function(event) {
console.log("DOM fully loaded and parsed");
});
</script>
兼容性
DOMContentLoaded 现在支撑一切主流浏览器,IE9 今后也支撑, 更多请看can I use?
假如要兼容 IE,则须要分外两个事宜,在 IE8 中,能够运用 readystatechange 事宜来监测 DOM 文档是不是加载终了,在更早的 IE 版本能够经由过程每隔一段时刻用 try/catch 实行一次 document.documentElement.doScroll(‘left’) 来监测这一状况, 由于这条代码在 DOM 加载实行终了之前会抛出毛病(throw an error)
依据以上的诠释,我们能够写一个兼容 IE 的 DOMContentLoaded 事宜from
// if IE
function IEContentLoaded (w, fn) {
var d = w.document, done = false,
// only fire once
init = function () {
if (!done) {
done = true;
fn();
}
};
// polling for no errors
(function () {
try {
// throws errors until after ondocumentready
d.documentElement.doScroll('left');
} catch (e) {
setTimeout(arguments.callee, 50);
return;
}
// no errors, fire
init();
})();
// trying to always fire before onload
d.onreadystatechange = function() {
if (d.readyState == 'complete') {
d.onreadystatechange = null;
init();
}
};
}
试验分割线
现在许多库都完成了兼容性的页面加载完成事宜,也许思绪是先推断 document.readyState === ‘complete’ 是不是为真,假如为真则直接实行剧本,不然才将剧本绑定到页面加载完成的事宜,然后依据 document 是不是有 addEventListener 来辨别主流浏览器和 IE 浏览器,由于 IE9 及今后基础和主流浏览器一样的规范,所以重要用来辨别 IE8 及以下,关于主流浏览器采纳 DOMContentLoaded + window.load, 关于 IE8 及以下,采纳 onreadystatechange + window.onload + doScroll。
这里要注意, onreadstatechange 事宜并不牢靠,假如页面中存在图片的时刻,能够反而在 onload 事宜今后才触发,一般来讲,它只能正确地实行页面不包括二进制资本或许异常少或许被缓存为时作为一个备选计划
function domReady(fn) {
var ready = false,
top = false,
doc = window.document,
root = doc.documentElement,
modern = doc.addEventListener,
add = modern ? 'addEventListener' : 'attachEvent',
del = modern ? 'removeEventListener' : 'detachEvent',
pre = modern ? '' : 'on',
init = function(e) {
if (e.type === 'readystatechange' && doc.readyState !== 'complete') return;
(e.type === 'load' ? window : doc)[del](pre + e.type, init, false);
if (!ready && (ready = true)) fn.call(window, e.type || e);
},
poll = function() {
try {
root.doScroll('left');
} catch(e) {
setTimeout(pull, 50);
return;
}
init('poll');
};
if (doc.readyState === 'complete') fn.call(window, 'lazy');
else {
if (!modern && root.doScroll) {
try {
top = !window.frameElement;
} catch(e) {}
if (top) poll();
}
doc[add](pre + 'DOMContentLoaded', init, false);
doc[add](pre + 'readystatechange', init, false);
window[add](pre + 'load', init, false);
}
}