时间线 解析与渲染 封装文档解析完毕函数

发布于:2022-11-28 ⋅ 阅读:(232) ⋅ 点赞:(0)

时间线

时间线:浏览器开始加载页面的那一刻到这个页面完全加载完毕这个过程中 按顺序发生的每一件事情的总流程
1.document对象 js就起作用了
2.解析文档:从html文档写的第一行东西开始浏览器会从第一行阅读到最后一行 这个过程在传统浏览器种只是在阅读
解析文档的同时会构建DOM树同时进行3构建CSSOM document.readyState = ‘loading’ 加载中
3.遇到link js引擎开新的线程异步加载css外部文件 遇到style 构建CSSOM
4.如果没有设置异步加载的script 阻塞文档解析 等待js脚本加载并且执行完成后 继续解析文档
5.如果有异步加载的script 异步加载js脚本 不阻塞解析文档 (但是异步脚本中不能使用document.write())
6.解析文档如果遇到img 先解析这个节点 只要写了src 就会创建加载线程 异步加载图片资源 不阻塞解析文档
7.文档解析完成 document.readyState = ‘interactive’ 解析完成
8. 如果设置defer script js脚本开始按照顺序执行 defer要在文档解析完成后执行
9. 文档解析完成后 会触发DOMContentLoaded事件 监听这个事件就知道文档什么时候解析完 文档解析完不代表资源加载完 这个事件触发后 同步的脚本执行阶段就变成了事件驱动阶段
10.async script 加载并执行完毕 img等资源加载完毕 window对象种的onload事件才触发 document.readyState = ‘complete’ 加载完成

window.onload 与 DOMContentLoaded的区别
window.onload是在文档解析完成后并且全部js加载执行完毕 img等资源加载完毕后才会触发
DOMContentLoaded是在文档解析完成后就触发

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style></style>
  </head>
  <body>
    <div></div>
    <script>
      console.log(document.readyState);
      document.onreadystatechange = function () {
        console.log(document.readyState);
      };
      document.addEventListener(
        'DOMContentLoaded',
        function () {
          console.log('DOMContentLoaded');
        },
        false
      );
    </script>
  </body>
</html>

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        width: 100px;
        height: 100px;
        background-color: #000;
      }
    </style>
  </head>
  <body>
    <div></div>
    <script src="./index.js" async="async"></script>
  </body>
</html>
document.write('123');

在这里插入图片描述

当直接在script标签内使用document.write时创建的内容会在scirpt标签下添加
此时scirpt标签还没有构建完成 页面还没有开始渲染 此时正常追加

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        width: 100px;
        height: 100px;
        background-color: #000;
      }
    </style>
  </head>
  <body>
    <div></div>
    <script>
      document.write('<h1>abc</h1>');
    </script>
  </body>
</html>

在这里插入图片描述

window.onload 要等文档解析 并且DOM树CSS树渲染树构建完成 并且渲染完 并且资源(图片资源等src)加载完后才触发

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        width: 100px;
        height: 100px;
        background-color: #000;
      }
    </style>
  </head>
  <body>
    <div></div>
    <script>
      window.onload = function () {
        document.write('<h1>abc</h1>');
      };
    </script>
  </body>
</html>

在这里插入图片描述

封装 domReady

文档解析完毕函数

      function domReady(fn) {
        if (document.addEventListener) {
          document.addEventListener(
            'DOMContentLoaded',
            function () {
              document.removeEventListener('DOMContentLoaded', arguments.callee, false);
              fn();
            },
            false
          );
        } else if (document.attachEvent) {//兼容ie
          document.attachEvent('onreadystatechange', function () {
            if (this.readyState === 'complete') {
              document.attachEvent('onreadystatechange', arguments.callee);
              fn();
            }
          });
        }
				// 兼容ie6,7 有一个doScroll api控制滚动条 ,文档没解析完会报错
        if (document.documentElement.doScroll && typeof window.frameElement === 'undefined') {
          try {
            document.documentElement.doScroll('left');
          } catch (error) {//一但报错就延迟 知道不报错
            return setTimeout(arguments.callee, 20);
          }
          fn();
        }
      }
本文含有隐藏内容,请 开通VIP 后查看