vue-router为什么会加载两遍dom?_DOM探索之-domReady

还记得刚开始学习JavaScript时候,经常会犯这样的错误:

  Dom not ready

最后发现结果并不是我们想要的,文字并没有变成红色,我想最先入门学习JavaScript操作DOM时候多多少少会遇到这种困惑和错误,其实出现这种问题的原因就是我们没有区分HTML标签和DOM节点的区别的缘故了,由这个问题就引出下面要说的domReady和浏览器渲染解析原理了。

什么是domRead

html是一种标记语言,它告诉我们这个页面有什么内容,但行为交互是需要通过DOM操作来实现的。我们不要以为有两个尖括号就以为它是一个DOM了,html标签要通过浏览器解析才会变成DOM节点,当我们向地址栏传入一个url的时候,我们开始加载页面,就能看到内容,在这期间就有一个DOM节点构建的过程。节点是以树的形式组织的,当页面上所有的html都转换为节点以后,就叫做DOM树构建完毕,简称为domReady。

那么浏览器是如何将html标签解析变成DOM节点的呢?

实际上浏览器是通过渲染引擎来实现的。渲染引擎的职责就是把请求的内容显示到浏览器屏幕上。默认情况下渲染引擎可以显示html、xml文档及图片。通过插件(浏览器扩展)它可以显示其他类型的文档,比如我们安装pdf viewer插件,我们就可以显示pdf文档。这里专注渲染引擎的主要用途,即是将css格式化的html和图片在浏览器上进行显示。

浏览器渲染引擎的基本渲染流程

浏览器渲染要做的事就是把CSS,HTML,图片等静态资源展示到用户眼前。

07394260250e65316d85a93ff79cfb74.png

渲染引擎首先通过网络获得所请求文档的内容,通常以8k分块的方法来完成:

786f8ecc62697837e635f802241f46c7.png

上图就是html渲染的基本过程,但这并不包含解析过程中浏览器加载外部资源,比如图片、脚本、iframe等的一些过程。说白了,上面的4步仅仅是html结构的渲染过程。而外部资源的加载在html结构的渲染过程中是贯彻始终的,即便绘制DOM节点已经完成,而外部资源仍然可能正在加载或者尚未加载。

Webkit主要渲染流程

Firefox浏览器Gecko渲染流程跟Webkit内核渲染类似,大同小异,WebKit 和 Gecko 使用的术语略有不同,但整体流程是基本相同的。这里以Webkit内核作为例子来说明浏览器渲染的主要流程。

浏览器的渲染原理并非三言两语,几个图就能说明白的,上图说的只是介绍一个大环节的过程和步骤,这里抛砖引玉象征性说个大概,更多关于浏览器内部工作原理的文章,请阅读:浏览器的工作原理:新式网络浏览器幕后揭秘

domReady的实现策略

上面的各个代码实例中,并没有考虑domReady,程序也能正常运行,因为我们把javascript代码写在了body元素最后的位置。因为浏览器是从上到下,从左向右渲染元素的,这样实例中的js代码一定在domReady之后去执行的。那为什么还要用domReady呢?事实上,我们在编写大型项目的时候,js文件往往非常多,而且之间会相互调用,大多数都是外部引用的,不把js代码直接写在页面上。这样的话,如果有个domReady这个方法,我们想用它就调用,不管逻辑代码写在哪里,都是等到domReady之后去执行的。

window.onload方法,表示当页面所有的元素都加载完毕,并且所有要请求的资源也加载完毕才触发执行function这个匿名函数里边的具体内容。这样肯定保证了代码在domReady之后执行。使用window.onload方法在文档外部资源不多的情况下不会有什么问题,但是当页面中有大量远程图片或要请求的远程资源时,我们需要让js在点击每张图片时,进行相应的操作,如果此时外部资源还没有加载完毕,点击图片是不会有任何反应的,大大降低了用户体验。那既然window.onload方法不可行,又该怎么做呢

你肯定想到了jquery中的$(document).ready(function(){})方法了,其实jquery中的domReady应该和window.onload的实现原理是大同小异的。为了解决window.onload的短板,w3c 新增了一个 DOMContentLoaded 事件。

这里提到了DOMContentLoaded事件,这里由于篇幅有限,就不多做介绍,这里面也有很多细节可以学习,有兴趣的童鞋,可以看看我之前收藏的两篇文章:

你不知道的 DOMContentLoaded

浅谈DOMContentLoaded事件及其封装方法

学习就是一个无底洞,因为深不可测,才让人不断探索。

参考jquery中domReady的实现原理,来看一下javascript中domReady的实现策略。

在页面的DOM树创建完成后(也就是HTML解析第一步完成)即触发,而无需等待其他资源的加载。即domReady实现策略:

1. 支持DOMContentLoaded事件的,就使用DOMContentLoaded事件。2. 不支持的就用来自Diego Perini发现的著名Hack兼容。兼容原理大概就是通过IE中的document,documentElement.doScroll('left')来判断DOM树是否创建完毕。

JavaScript实现domReady,【domReady.js】

function myReady(fn){  //对于现代浏览器,对DOMContentLoaded事件的处理采用标准的事件绑定方式  if ( document.addEventListener ) {  document.addEventListener("DOMContentLoaded
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值