为何document.onload等事件不触发,onreadystatechange却触发两次?
现象原因说明
三个事件处理函数不触发的原因
你在控制台打印document看到onload/onloadstart/onloadend属性,只是浏览器给所有支持事件处理的DOM节点预留的通用属性位,不代表document对象真的会接收这三个事件:
loadstart、loadend属于资源加载进度事件,只会派发到具体的资源加载元素(比如<img>、<script>标签),以及全局window对象上,document节点本身不会收到这两个事件的派发,绑定的处理函数自然不会执行。- 页面整体加载完成的
load事件,派发目标同样是window而非document,你给document.onload赋值本质只是给document对象加了个存函数的普通属性,没有对应事件触发,函数永远不会被调用。
如果要监听这几个事件,把处理函数绑定到window对象上即可,比如写window.onload = function(){ alert("window loaded") }就能正常触发。
document.onreadystatechange触发两次的原因
readystatechange是document对象原生支持派发的事件,触发时机和document.readyState的状态变更完全绑定。页面从加载到渲染完成的过程中,readyState会经历两次明确的状态变更,对应两次事件触发:
- 第一次触发:HTML解析器完成整个DOM树的解析,此时
document.readyState从初始的loading变为interactive,这时候DOM结构已经可以被正常访问。 - 第二次触发:页面所有依赖的外部资源(图片、样式表、iframe等)全部加载完成,此时
document.readyState从interactive变为complete,这个时机和window的load事件触发时机非常接近。
你写的测试脚本放在<div>节点之前,脚本执行时刚好处在readyState为loading的阶段,后续两次状态变更都能被你绑定的处理函数监听到,所以会弹出两次alert。
内容的提问来源于stack exchange,提问作者peter
相关产品推荐
相关产品推荐

