对前端同学而言,loade,unload,DOMContentLoaded等页面加载过程中会触发的事件肯定是都接触过,不过要是具体问各个事件的区别,我就不是那么能清晰的解答上来的了。正好刚刚在无阻塞脚本那看到了DOMContentLoaded事件,就来翻翻具体文档详细看一下各个事件吧。常言道温故而知新,让我们一起回头看一下

触发时机

先看下各个事件的触发时机(参考自MDN)

DOMContentLoaded

当初始html文档完全加载并解析之后触发,无需等待样式、图片、子frame结束。作为明显的对比,load事件只有一个页面完全被加载时才触发。改用DOMContentLoaded的地方常常是load来代替,这是错误的。 tips: 有许多通用和独立的库提供跨浏览器方法来检测 DOM 是否已准备就绪即ready事件,后面我们可以看下zepto的实现

load

当一个资源及其依赖的资源结束加载时触发。从这里可以看到需要等待依赖资源的结束加载。

readystatechange

document有readyState属性来描述document的loading状态,readyState的改变会触发readystatechange事件.

  • loading

    文档仍然在加载

  • interactive

    文档结束加载并且被解析,但是想图片,样式,frame之类的子资源仍在加载

  • complete

    文档和子资源已经结束加载,该状态表明将要触发load事件。

因此,我们同样可以使用该事件来判断dom的加载状态。
但并非所有对象都会经历 readyState 的这几个阶段,有时候需要

beforeunload

当浏览器窗口,文档或其资源将要卸载时,会触发beforeunload事件。这个文档是依然可见的,并且这个事件在这一刻是可以取消的.
如果处理函数为Event对象的returnValue属性赋值非空字符串,浏览器会弹出一个对话框,来询问用户是否确定要离开当前页面(如下示例)。有些浏览器会将返回的字符串展示在弹框里,但有些其他浏览器只展示它们自定义的信息。没有赋值时,该事件不做任何响应。 tip:2011年5月25号起,html5中指出,该事件中调用window.alert(), window.confirm(), and window.prompt()方法将会被忽略。

unload

当文档或者一个子资源将要被卸载时,在beforeunload 、pagehide两个事件之后触发。
文档会处于一个特定状态。

  • 所有资源仍存在 (图片, iframe 等.)
  • 对于终端用户所有资源均不可见
  • 界面交互无效 (window.open, alert, confirm 等.)
  • 错误不会停止卸载文档的过程

页面加载中的执行顺序

从上面的定义,我们可以得出一个比较清晰的顺序了。

  1. 页面加载开始,首先肯定是先发出加载资源的请求,加载未完成之前,不触发任何事件。

  2. document加载结束并解析,此时css等其他资源未加载完成。

    此时readyState为'interactive',表明document已经load并解析完成,触发 readystatechange,然后触发DOMContentLoaded(在大多数浏览器上的表现如此)。捎带提一句,此时,加载完成且带有defer标记的脚本,会按顺序开始执行。

  3. css、img等子资源加载完成之后

    此时触发window.load事件

  4. 点击关闭标签或者刷新时,会依次触发beforeunload、unload事件。

可能概念看的有点枯燥,还是看下代码比较清晰。大家可以看下,下面的代码会依次输出什么。

<!DOCTYPE html>
<html><head><title>文档加载事件</title><script>document.addEventListener("DOMContentLoaded", function (event){console.log("初始DOM 加载并解析");});window.addEventListener("load", function (event){console.log("window 所有资源加载完成");});document.onreadystatechange = function (){console.log(document.readyState)if (document.readyState === "complete") {console.log('初始DOM,加载解析完成')}}window.addEventListener("beforeunload", function (event){console.log('即将关闭')event.returnValue = "\o/";});window.addEventListener('unload', function (event){console.log('即将关闭1');});</script><link rel="stylesheet" href="./test.css">
</head><body><div id="root">dom事件</div><script src="./index.js"></script>
</body></html>

依次输出如下:

    interactive //(index):15初始DOM 加载并解析 //(index):8complet//(index):15初始DOM,加载解析完成//(index):17window 所有资源加载完成//(index):11//点击关闭按钮即将关闭即将关闭2

关于ready

像jquery、zepto等类库中都有document一个ready方法,来确保我们的操作在初始dom加载之后进行,原生dom定义里是没有这个api的,是大牛们封装了一下判断的过程,提供我们以便利。
有了前面的例子,让我们猜一下他们是怎么实现的。

  1. ready对应的状态是初始化dom已经加载完成,我们来看一下什么情况下对应该情况。

    有下面几个状态,complete、interactive 还有一个DOMContentLoaded也是初始dom加载完成,当然还有load事件,显然这里不会用到它,相对其他状态而言有点太晚了。

  2. 确定触发条件之后,下面的实现就简单了,判断就行了。

以zepto为例,我们看下实现:

//声明变量,不只使用interactive,是因为前面提到这些状态不一定全部出现
readyRE = /complete|loaded|interactive/ready: function(callback){// need to check if document.body exists for IE as that browser reports// document ready when it hasn't yet created the body elementif (readyRE.test(document.readyState) && document.body) callback($)else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false)return this}

至此,介绍就结束了。对我而言,明了原来不太清楚的概念,希望对大家也有所帮助。

更新

评论区中有同学提到DOMContentLoaded时机的问题,即css 没有加载完成,应该不会触发 DOMContentLoaded。
这个问题可能会存在,举个例子:

<div id="example-root">测试DOMContentLoaded 与css</div>
//随手拿了一段css
<link rel="stylesheet" href="https://m.jb51.net/skin/mobile2017/css/common.css">
<script>document.addEventListener('DOMContentLoaded', function (){alert('DOMContentLoaded 触发');});</script>

此时可以看到触发时,确实是css已经加载完成。 但是先不要忙着下结论,代码换一下顺序:

<div id="example-root">测试DOMContentLoaded 与css</div>
<script>document.addEventListener('DOMContentLoaded', function (){alert('DOMContentLoaded 触发');});</script>
//随手拿了一段css
<link rel="stylesheet" href="https://m.jb51.net/skin/mobile2017/css/common.css">

这时候可以看到,触发DOMContentLoaded时,css依旧处于pending状态 如果会等待css的完成,显然此时css应该加载完成了。

结论

DOMContentLoaded触发确实不会等待css加载完成的。上述现象的出现不是DOMContentLoaded时机的问题,是js执行顺序问题。 js监听事件的时候,css已经加载完成了,所以给人一种错觉。

DOMContentLoaded、readystatechange、load、ready详谈相关推荐

  1. alert 返回页面 刷新_页面生命周期:DOMContentLoaded,load,beforeunload,unload

    DOMContentLoaded,load,beforeunload,unload HTML 页面的生命周期包含三个重要事件: DOMContentLoaded -- 浏览器已完全加载 HTML,并构 ...

  2. 页面生命周期:DOMContentLoaded,load,beforeunload,unload

    DOMContentLoaded,load,beforeunload,unload HTML 页面的生命周期包含三个重要事件: DOMContentLoaded -- 浏览器已完全加载 HTML,并构 ...

  3. onload、DOMContentLoaded、$(document).ready(fn)、$(document).load(fn)

    特性 onload DOMContentLoaded $(document).ready(fn) $(document).load(fn) 执行时机 页面全部加载完才会执行 DOM结构加载完毕就能执行 ...

  4. DOMContentLoaded与load的区别

    JavaScript 中的以下代码 : Window.onload= function (){//代码 } 等价于 Jquery 代码: $(window).load(function (){//代码 ...

  5. DOM加载过程中ready和load的区别

    在浏览器地址栏输入URL地址,浏览器开始加载页面时,有以下几个过程 1.浏览器开始解析HTML文档 2. 浏览器遇到HTML文档中的<script>元素以及CSS样式文件,并且没有asyn ...

  6. ready与load的区别

    JQuery里有ready和load事件 $(document).ready(function() {// ...代码... }) //document ready 简写 $(function() { ...

  7. DOMContentLoaded 与onload区别以及使用

    一.何时触发这两个事件? 1.当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了. 2.当 DOMContentLoaded 事件触发时,仅当DOM加载完 ...

  8. jQuery-1.9.1源码分析系列(六) 延时对象应用——jQuery.ready

    还记不记得jQuery初始化函数jQuery.fn.init中有这样是一个分支 //document ready简便写法$(function(){-}) } else if( jQuery.isFun ...

  9. jQuery的ready方法实现原理分析

    jQuery中的ready方法实现了当页面加载完成后才执行的效果,但他并不是window.onload或者doucment.onload的封装,而是使用 标准W3C浏览器DOM隐藏api和IE浏览器缺 ...

  10. Rails 4:如何使用带有turbo-links的$(document).ready()

    本文翻译自:Rails 4: how to use $(document).ready() with turbo-links I ran into an issue in my Rails 4 app ...

最新文章

  1. 练习5-2 找两个数中最大者 (10 分)
  2. Qlikview 的服务器
  3. 干货+福利!MySQL常见的面试题+索引原理分析!
  4. php+date+timezoe,PHP 字符串
  5. [js] XML与JSON有什么的区别?
  6. 改变文件权限的用户身份
  7. pyqt5优秀项目python_Python优秀开源项目Rich源码解析
  8. mysql 廖雪峰_讨论 - 廖雪峰的官方网站
  9. 【C++】字体文件解析(FreeType)
  10. itext 生成 PDF(一)
  11. 想要学习云计算,不知道如何开始?我来说下云计算的学习流程,分享一些学习资源。
  12. 什么是生成器 — 一篇文章让你看懂
  13. oracle查询三个月前的时间
  14. 【Python从零到壹】Python爬虫部分开篇
  15. FCN学习:Semantic Segmentation(摘自知乎)
  16. STM32下载中出现Flash Download failed - Target DLL has been cancelled报错
  17. xming Error: Can‘t open display:
  18. Ubuntu18.04|20.04 idea安装Consolas字体
  19. 【Android】Android界面设计
  20. java 构造函数和super

热门文章

  1. 「长乐集训 2017 Day1」区间 线段树
  2. Linux部署之批量自动安装系统之测试篇
  3. Android零基础入门第42节:自定义BaseAdapter
  4. python之模块 os
  5. 中文的习题解答中国人看懂, 英文的习题解答外国人能看懂
  6. linux常用命令技巧
  7. PB数据窗口自动换下一页
  8. C#中的常量、类型推断和作用域
  9. initwithcoder和 initwithframe 区别?
  10. 400,404,500报错页面总结