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是一个非常常用兼容处理,但是篇幅问题,就下次吧。

    总结

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

  • 相关阅读:
    Google app engine python 2.5.4 安装ssl
    Ubuntu 10.04分辨率
    Google Voice 国内用户开通全攻略(图文)
    (linux)查看及修改文件权限以及相关
    InstallAnyWhere使用笔记制作升级补丁时的一些判断
    openoffice 编译依赖关系履历
    匹配连续的任意字词
    BT3 无线密码
    All roads lead to Rome, some smooth, some rough.
    test
  • 原文地址:https://www.cnblogs.com/aoximin/p/12394990.html
Copyright © 2011-2022 走看看