zoukankan      html  css  js  c++  java
  • 前端页面生命周期

    前言

    对页面声明周期的总结与回忆。

    下文均为个人测试得出的结论,如有不对望指出。

    正文

    了解页面声明周期面前,需要了解几个概念。

    1.在页面中dom加载与css加载是异步的。但是呢,也不绝对,比如内联css是同步的。

    2.页面中js加载与dom加载是同步的,但是也不绝对,这个比较复杂后文介绍。

    先看下页面的生命周期:

    DomContentLoaded:dom加载完毕,但是外部资源可能没有加载完毕,如样式表、图片资源等。

    load:浏览器所有资源加载完毕。

    beforunload/unload 当用户离开页面的时候触发。

    在我们写demo的时候,往往这样写:

    window.onload=function(){
    }
    

    可能会把我们初始化的资源都写在onload中,但是在正常项目中,这样写的效率是不高的。

    因为DomContentLoaded 这个时候就已经加载完了我们的Dom,这个时候就可以操作dom了。

    但是因为样式没有加载,如果需要动态去获取样式的一些属性,那么就需要在onload中了。

    DOMContentLoaded

    用法:

    document.addEventListener("DOMContentLoaded",ready);
    function ready()
    {
      console.log("ready");
    }
    

    因为前面提及到dom加载与资源加载是异步的,这时候不要去拿取资源,所以不要去拿取资源文件。

    前面提及UI渲染线程与JS引擎是互斥的,即使script 引用是以资源文件src方式引用的,这时候依然会等待js的加载。

    这时候就会有一些小问题,如果js加载时候过程过于漫长,那么这样用户会不会以为宕机了,会不会怀疑有人删库跑路了?

    如何提高用户体验度?

    这时候就有async 与 defer 来帮助了。

    <script type="text/javascript" src="demo_async.js" async="async"></script>
    
    <script type="text/javascript" defer="defer">
    alert(document.getElementById("p1").firstChild.nodeValue);
    </script>
    

    对了,async只是针对外部资源,也就是对src有效,内联js无效,defer对内联与src都有效。

    <script src="./test.js" async='async'>
    </script>
    <script>
    document.addEventListener("DOMContentLoaded",ready);
    function ready()
    {
      console.log("ready");
    }
    </script>
    

    test.js

    console.log("out script");
    

    defer,我就不演示了,来介绍这两个有什么不同吧。

    名称 特性
    async 比如有几个带有async的js文件,这几个执行文件顺序是不知道的,也就是说async的资源文件是异步的
    defer 会根据我们在页面中书写的顺序执行

    但是我建议不使用defer,看起来defer更好,实际上defer有致命性问题,只有 Internet Explorer 支持 defer 属性。

    看到这里开心不开心?又少学了一样东西。

    但是呢,这个async 水有点深,怎么说呢?

    我刚才提及到了DOMContentLoaded会先执行,其实也不一定。

    为何这么说呢?比如我们页面有很多不是async的js,然后可能async的资源文件还有缓存,当async加载完毕后,那么不就要先执行async的资源。

    所以async应该理解为独立于dom生命周期加载执行。

    举一个async的一个好处的例子,也是我在网上看到的。

    Firefox, Chrome和Opera会在DOMContentLoaded执行时自动补全表单。

    但是当人们看到页面的时候表单还没有补齐。这时候就是DOMContentLoaded被前面执行的js给堵塞了。

    这里提及到另外一个现代主义浏览器的问题,为什么我们将js脚本放在body最后加载,是否可以减少到达DOMContentLoaded的时间?

    其实不能,我们知道让js放在dom元素可以让docuemnt.getElementById 可以拿到元素,但是这依然可以在DOMContentLoaded中执行,似乎起不好什么优化效果。

    相对以前的浏览器,现在浏览器不对等待dom加载完毕后渲染,而是会先加载渲染一部分。

    但是同样有问题,比如我们要操作一些dom,但是dom太多,我们的js又在最后,那么很有可能会乱。

    所以我们打开大型网页的时候,常常见到嵌入到dom元素直接的。

    像这样:

    <div></div>
    <script></script>
    <div></div>    
    

    但是,DOMContentLoaded依然要等到dom加载完毕。在这里,其实DOMContentLoaded还没有介绍完,因为还有ie的兼容问题会在下面提及。

    window.onload

    这个不多介绍了,window对象上的onload事件在所有文件包括样式表,图片和其他资源下载完毕后触发。

    window.onbeforeunload

    有些网页在我们在离开的时候,会问我们是否保存。

    就是用这个实现的。

    支持情况:

    IE、Safari 完美支持

    Firefox、Chrome 不支持文字提醒信息

    Opera 不支持

    window.onunload

    用户离开页面的时候使用。

    支持情况:

    IE、Safari 完美支持

    Firefox、Chrome 不支持文字提醒信息

    Opera 不支持

    readyState

    这个用的并不多,一般用来兼容ie的。

    但还有有些用的。比如我们使用async,异步的时候希望去操作dom,不知道async是在加载后执行还是加载前,所以可以这样。

    if (document.readyState == 'loading') {
      document.addEventListener('DOMContentLoaded', dosomething);
    } else {
      dosomething();
    }
    function dosomething() { /*.xxxxx..*/ }
    

    回过来看下有什么状态:

    一个document 的 Document.readyState 属性描述了文档的加载状态。

    loading / 正在加载
    document 仍在加载。

    interactive / 可交互

    文档已被解析,"正在加载"状态结束,但是诸如图像,样式表和框架之类的子资源仍在加载。
    

    complete / 完成

    文档和所有子资源已完成加载。表示 load 状态的事件即将被触发。
    

    当这个属性的值变化时,document 对象上的readystatechange 事件将被触发。

    这样我们可以监听到html的加载状态了。

     document.addEventListener('readystatechange', () => log('readyState:' + document.readyState));
    

    有一点上面可能产生误解:是image的onload先执行呢?还是document.readyState 的complete 先执行呢?

    这个不一定。因为如果image是最后一个加载的资源,回调的可能就先是complete。如果image不是最后一个加载的资源,那么就是image的onload了。

    但是complete 回调的时候肯定资源都加载完成了。

    本来打算在这里介绍ie兼容的,因为Document.readyState是一个非常常用兼容处理,但是篇幅问题,就下次吧。

    总结

    以上来自个人理解,如有不对,望指出。

  • 相关阅读:
    ionic localstorage
    angular 中文鏈接
    把jqmobi 變成jQuery 的插件 從此使用jQuery
    jqmobi 的一些設置
    ionic ngcordova map 地圖
    ionic pull to refresh 下拉更新頁面
    json 對象的序列化
    鍵盤彈出,頁面佈局被推上去了.....
    Cordova V3.0.0中config.xml配置文件的iOS Configuration
    android ios 只能輸入數字 不能輸入小數點的 函數 cordova
  • 原文地址:https://www.cnblogs.com/aoximin/p/12394990.html
Copyright © 2011-2022 走看看