-
1、 事件解析及事件闭环知识点:
-
1-1、 load事件是window里面比较常见的一个事件,对应的Dom事件onload更是Dom2开始就已经作为了dom的基础标准事件了
- 示意:MDN原文
The load event is fired when the whole page has loaded, including all dependent resources such as stylesheets and images. This is in contrast to DOMContentLoaded, which is fired as soon as the page DOM has been loaded, without waiting for resources to finish loading.- 这里面有两句话,阐述两个含义:
- 1、load事件表示当个整个页面加载完毕,包括所有依赖的诸如样式表和图片等页面资源都加载完毕时将会触发load事件
- 2、另一个与load事件相似的DOMContentLoaded事件则不会,DOMContentLoaded事件是在页面的Dom被解析加载之后就会被触发,而不用像load一样等到页面所依赖的资源加载完毕在执行。【简单概述:DOMContentLoaded事件早于load事件】
- 3、是不是很熟悉,没错,了解jquery开发的人都知道,这个DOMContentLoaded就是对应jquery的ready()事件的时机,【jquery的源码里面也确实这样做的】
-
1-2、 那么load作为标准的dom事件源,到底还有啥细节呢,我们接着往下看:
- 除了上面提的DOMContentLoaded事件,我们还得了解另外两个点:document.readyState属性及属性变化响应事件readystatechange【或者其handle事件:onReadystatechange】
- document.readyState属性
- MDN示意:
The Document.readyState property describes the loading state of the document.,意思就是:用来描述document的加载状态的 - 该属性按照加载的阶段划分为以下几个值:
- loading
- 【The document is still loading.】,document还在加载中,Dom还没被解析加载完成
- interactive
- 【The document has finished loading and the document has been parsed but sub-resources such as scripts, images, stylesheets and frames are still loading.】
- Dom已经加载完成,但是依赖的资源诸如样式表和图片还没完成,正在加载。
- 这个状态可以等价于DOMContentLoaded事件触发点
- complete
- 【 The document and all sub-resources have finished loading. The state indicates that the load event is about to fire. 】
- Dom已将完成加载,同时dom所依赖的资源诸如样式表和图片也已经记载完成,load事件将被触发。
- 这个状态明确表明,等价于load事件触发点
- MDN示意:
-
1-3、 至此总结load事件闭环的四个相关的知识点:load事件【对应handle:onload】、DOMContentLoaded事件【无对应handle】、document.readyState属性、readystatechange【对应handle: onReadystatechange】
-
-
2、看一看这个事件的应用场景
-
2-0、从Dom加载完成这个点出发,考虑如下一些比较常见的应用场景:
-
2-1、动态添加图片,在图片加载完成给予一些业务逻辑
const Img = new Image() Img.src='xxx' Img.onload = function() { console.log('图片加载完成了,可以写业务了') }; <!-- 或者 --> <img src="xxx" onload="loadImage()" > function loadImage(){console.log('图片加载完成了,可以写业务了')}-
2-2、批量图片记载完毕,给予一些业务逻辑
const imgArrs=['1.png','2.png','3.png'] let promiseAll = [], imgs = [], for (let i = 0; i < imgArrs.length; i++) { promiseAll[i] = new Promise((resolve, reject) => { imgs[i] = new Image(); imgs[i].src = imgArrs[i]; imgs[i].onload = function() { resolve(imgs[i]); }; imgs[i].onerror = function() { reject(imgs[i]); }; }) } Promise.all(promiseAll) .then(img => { // 全部图片加载完成 }) .catch(err=>{ // 加载出错了 })-
2-3、script标签加载内部或者外部js文件完毕,给予一些业务逻辑
<!-- 同样借助promise --> function loadScript(url){ return new Promise((resolve, reject) => { const scriptResource = document.createElement('script') scriptResource.type='text/javascript' scriptResource.src = url; scriptResource.async = 'async' scriptResource.defer = 'true'//根据情况决定要不要写,不写的话,加快页面解析 scriptResource.onload = function() { resolve("success"); }; scriptResource.onerror = function() { reject('fail'); }; document.body.appendChild(scriptResource); }) } loadScript('xxxx.js').then(img => { // js加载完成,写业务吧 }) .catch(err=>{ // js加载出错了 }) // 不经意的就封装了一个加载js文件的记载器,而且已经异步化了, // 这个对于vue和react来说,可能有时可以用到,在vue的mounted阶段和react的componentDidMount阶段时,去加载内部或者外部js资源
-
-
3、思考:写了这些应用场景,有几点还是可以思考的:
- new Promise返回的是个promise实例,可以进一步then
- 很多时候,常规的事件,同步的操作或请求,都可以进行promise异步化封装,这样用起来可能更好用【很多小程序或者企微的同步api,都可以经过这样一整套的封装输出】【这点很重要,现在的前端开发必须要有异步化改造思想(promise)】
-
4、 参考文献
- MDN: developer.mozilla.org/en-US/docs/… 【推荐】
- 衍生: juejin.cn/post/684490…