You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
在IE8中,可以使用readystatechange事件来检测DOM文档是否加载完毕.在更早的IE版本中,可以通过每隔一段时间执行一次document.documentElement.doScroll("left")来检测这一状态,因为这条代码在DOM加载完毕之前执行时会抛出错误(throw an error)。 MDN-readystatechange事件
https://wolfdu.fun/post?postId=5a362d1e25322c62a62e7b0a
当时我是懵逼的,原生js写DOM事件的冒泡?
首先对于DOM事件的冒泡,只知道DOM的事件会从子节点向父节点一级一级的冒泡,,,冒泡。
js绑定事件,不就是
$(...).on(...)
嘛,此时赶脚前端知识体系的崩塌,原生JavaScript中DOM相关操作方法记得的寥寥无几。既然痛点已经暴露如此彻底,那就好好的揭揭伤疤,回顾现在项目中的技术框架,spring MVC前端后端未完全分离,前端DOM相关操作重度依赖jQuery。当然这里不是说jQuery不好(jQuery是个非常优秀的js库),由于是野路子前端,基础本来就不够好的情况下
$
帮我做了太多事情,让我几乎遗忘了DOM本来的特性和JavaScript对它的实现和用法。接下来就来恶补一下相关知识吧,以下都是在学习过程发现比较优质的资源,和相关知识整理。
DOM is 瓦特?
DOM,文档对象模型(Document Object Model)。
它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。
DOM 有自己的国际标准,如DOM0,DOM1,DOM2,DOM3,DOM4,目前的通用版本是DOM 3。
实际并没有DOM0这个标准可以理解为历史的起点,感兴趣可以扒一扒这段历史。
浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree),所有的节点和最终的树状结构,都有规范的对外接口。这里的接口就是我们所说的DOM。
DOM节点
DOM的最小组成单位叫做节点(node)。节点类型一共有12种,这里介绍常用的7种类型。
所有节点对象都是浏览器(除IE)内置的Node对象的实例,继承了Node属性和方法。这是所有节点的共同特征。
每个节点都有一些基本属性如:nodeType属性,用于表明节点的类型,nodeName属性返回节点的名称,nodeValue属性表示当前节点本身的文本值。
通过一个实例来看看:
<body>
、<a>
等)更多DOM节点方法阮一峰-DOM 模型概述
真的知道DOMReady是啥吗?
初学JavaScript时,老师傅都会告诉我们要把JavaScript写在HTML的最底部,说是页面元素会有加载顺序,可能会出现页面元素还没有加载完,JavaScript代码就运行了,导致页面功能失效。
在我的理解中,这一直都是一个模糊的概念,那么我们来探一探究竟。
先来看看这个例子:
我们想让h1中的文字变成红色,但是结果却没有变化,看控制台会发现打印了一个异常
Uncaught TypeError: Cannot read property 'style' of null
,这也似乎印证了我们之前了解的模糊概念。那么从我们写好了HTML到渲染到页面发生了什么呢???HTML to DOM
浏览器中负责解析HTML的东东叫做**渲染引擎(rendering engine)**我们看一下渲染引擎是如何处理的。
渲染引擎首先通过网络获得所请求文档的内容,通常以8K分块的方式完成。
渲染引擎在取得内容之后的基本流程:
渲染引擎开始解析html,并将标签转化为内容树中的dom节点。
接着,它解析外部CSS文件及style标签中的样式信息。这些样式信息以及html中的可见性指令将被用来构建另一棵树——render树。
Render树构建好了之后,将会执行布局过程,它将确定每个节点在屏幕上的确切坐标。
再下一步就是绘制,即遍历render树,并使用UI后端层绘制每个节点。
我们来看看webkit渲染页面的大致流程:
这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html都解析完成之后再去构建和布局render树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容,比如图片、脚本、iframe等。
这里只是抛砖引玉如果想详细了解浏览器的工作原理可以戳这里浏览器内部工作原理
DOMReady的实现
在了解了以上知识后我们再来分析上面的问题,浏览器是从上到下,从左向右渲染元素的,在解析器遇到
<script>
标记时立即解析并执行脚本。此时文档的解析将停止,直到脚本执行完毕。如果脚本是外部的,那么解析过程会停止,直到从网络同步抓取资源完成后再继续,这里也就解答了我们遇到的问题。就是在HTML标签还没有解析成dom的时候我们就已经执行了JavaScript脚本,导致控制台异常,页面也没有效果。
这里就引入了DOMReady概念:
那我们将JavaScript脚本写在html底部是不是就完美解决这个问题了呢?
我们将JavaScript代码移动到html底部的时候,发现文字变成了红色。
这里我们结合日常开发的经验来思考这个问题,我们通常不会将JavaScript代码直接写在HTML代码中(生产中的业务逻辑通常比较复杂),而是通过
<script>
标签引入外部代码,其中js代码之间还会有调用关系,所以我们需要一个DOMReady的方法,来保证DOM树已经构建完成这样我们就可以在任何位置调用我们的逻辑代码了。window.onload
我们可以通过window.onload方法来达到目的:
可以发现
window.onload
方法是在所有外部资源都加载完之后调用的方法,但是我们之前了解的DOMReady完成的时候其他外部资源是有可能还处于加载过程中。这个方法虽然满足了DOMReady后调用,但是当外部资源很多的时候呢?那么页面很可能处于假死状态,这样就很影响用户体验了。DOMContentLoaded
既然我们需要在DOMReady完成的时候就执行JavaScript脚本,那我我们看看有木有刚刚好在DOMReady的时候执行的方法呢?是有的。
从上述描述我们就可以很清晰了解到,该方法的作用了。
但是这里还是有一个问题,那就是浏览器的兼容问题->“万恶的IE”
那么这里我们来看看我们常用的jQuery中DOMReady是如何实现的呢?
使用过jQuery都应该见到这样的代码
$(document).ready(function(){})
或者$(function(){})
可以看一看jQuery-ready源码这里我们自己来实现一个兼容各个浏览器的DOMReady方法基本策略和jQuery大同小异:
=͟͟͞͞( •̀д•́) 猴!说了那么多,我们来对比一下
window.onload
和DOMReady
之前差异:这是执行结果:
效果还是灰常明显的( ´´ิ∀´ิ` )
终于知道为什么书会越读越厚了(;´༎ຶД༎ຶ`) ,看来想要到达读薄的境界还有很长的路要走呀。
感觉是时候来回答大佬的问题了。 ( ͡° ͜ʖ ͡°)
大佬的问题
前面都是前言啊( ⊙ o ⊙ )啊!
这里才是正文~~~
用原生js写一个DOM事件的冒泡,我的理解,这个问题就是考察事件执行过程中在DOM节点间的传播。
那么是不是用一个示例来展示一个事件在执行过程中的传播过程就可以呢?( ͡° ͜ʖ ͡°)✧
(눈_눈)但是传播过程中我只知道有个事件的冒泡。。。
那么顺么是事件的传播呢?
事件的传播
也就是说一个子节点事件的触发会在多个父子节点间触发同样的事件?
我们来看一个示例:
运行结果:
可以发现click事件被触发了四次:
<p>
节点的捕获阶段和冒泡阶段各1次,<div>
节点的捕获阶段和冒泡阶段各1次。<div>
向<p>
传播时,触发<div>
的click事件;<div>
到达<p>
时,触发<p>
的click事件;<p>
时,触发<p>
的click事件;<p>
传回<div>
时,再次触发<div>
的click事件。以下是事件在DOM树中大致传播流程:
事件传播的最上层对象是window,接着依次是document,html(document.documentElement)和body(document.dody)。也就是说,如果
<body>
元素中有一个<div>
元素,点击该元素。事件的传播顺序,在捕获阶段依次为window、document、html、body、div,在冒泡阶段依次为div、body、html、document、window。那么我们一句话事件冒泡:
当一个DOM元素上的事件被触发的时候(如:示例中p的点击事件),同样的事件将会在那个元素的所有父元素中被触发,从这个事件会从原始元素开始一直传递到DOM树的最上层,这一过程被称为事件冒泡。
具体关于事件冒泡的应用就不在这里扩展了,在日常开发中也经常遇到。
以上就是和大佬聊完之后的一些思考。
总结
每次和比自己厉害的人(哪怕是看起来厉害(╯▔(▔)╯)聊天,都能让自己看到自己的不足。经过这次也再次感觉到学无止境,前路总有自己不知道的东西,这TM什么时候才是头呀(;´༎ຶД༎ຶ´),
同时我还发现我们在习惯了jQuery之后,似乎我们对于很多JavaScript操作DOM的方法是都知之甚少,例如事件的绑定感觉就只限于
$(...).on(...)
了,导致在使用vue,react这些框架时会有很多疑惑,原生js操作DOM十分不顺手。看来要好好看看You-Dont-Need-jQuery,来减少依赖jQuery带来的恐惧呀,不过这也不是jQuery的锅,学艺不精而已,基础的东西才是根本呀。以下是本次参考学习资料:
慕课视频--DOM探索之基础详解篇
大牛整理的视频笔记--jawil整理的笔记
阮大大-JavaScript 标准参考教程
若文中有知识整理错误或遗漏的地方请务必指出,非常感谢。如果对你有一丢丢帮助或引起你的思考,可以点赞鼓励一下作者=^_^=
The text was updated successfully, but these errors were encountered: