扫码关注官方订阅号
Title 哈哈0 哈哈1 哈哈2 哈哈3 哈哈4
感谢各位指点,找到问题答案了.后面是一个小结:https://icbd.github.io/wiki/w...
拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...
代码自上而下执行,照你的代码是一开始className是red,执行到for循环的时候,更新className为green。
className
red
for
green
写成这样你就明白了
for (var i = 0, len = liArr.length; i < len; i++) { console.log('start:'+ JSON.stringify(liArr)); liArr[0].className = 'green'; // 每次都改变第一个元素 console.log('over:'+ JSON.stringify(liArr)); }
这是document.getElementsByClassName和document.querySelectorAll的返回值不同造成的,W3C规定:前者的返回值是一个动态的 Node List,后者返回的是一个静态的 Node List,类似于快照。https://www.zhihu.com/questio...
querySelectorAll返回的元素集合中的元素是非实时的,这就是这个问题最关键之处,也是与getElement...系列的最大区别。注意这个字眼“实时”。
1) 渲染引擎把HTML文档解析成DOM树,把标签转换成DOM节点。 2) Gecko(Firefox):在解析HTML文档的同时,渲染引擎会把文档内的样式和外部CSS文件解析成CSS规则树。而Webkit不会生成CSS规则树。3) 渲染器是在文档解析和创建DOM节点后创建的,会计算DOM节点的样式信息。如果元素的display属性被设置成了none,或者如果元素的子孙继承了display:none,该元素的渲染器不会被创建。节点的子类和display属性一起决定为该节点创建什么样的渲染器。渲染器是渲染树的节点。 Gecko(Firefox):DOM树和CSS规则树结合之后,形成了Style Content Tree。将Style Content Tree和渲染树关联,就完成了渲染树。 渲染树包含多个视觉属性(如颜色和尺寸),属性的排列顺序是在屏幕上显示的顺序。 4) 渲染树构建出来之后,就进入布局阶段,为渲染树的每个节点分配一个屏幕上的确切坐标。 5) 最后一步,就是遍历渲染树,通过用户界面后端(UI Backend)将每个节点绘制出来。
1) 渲染引擎把HTML文档解析成DOM树,把标签转换成DOM节点。
2) Gecko(Firefox):在解析HTML文档的同时,渲染引擎会把文档内的样式和外部CSS文件解析成CSS规则树。而Webkit不会生成CSS规则树。3) 渲染器是在文档解析和创建DOM节点后创建的,会计算DOM节点的样式信息。如果元素的display属性被设置成了none,或者如果元素的子孙继承了display:none,该元素的渲染器不会被创建。节点的子类和display属性一起决定为该节点创建什么样的渲染器。渲染器是渲染树的节点。
Gecko(Firefox):DOM树和CSS规则树结合之后,形成了Style Content Tree。将Style Content Tree和渲染树关联,就完成了渲染树。 渲染树包含多个视觉属性(如颜色和尺寸),属性的排列顺序是在屏幕上显示的顺序。
4) 渲染树构建出来之后,就进入布局阶段,为渲染树的每个节点分配一个屏幕上的确切坐标。
5) 最后一步,就是遍历渲染树,通过用户界面后端(UI Backend)将每个节点绘制出来。
注:这是一个渐进的过程。渲染引擎不会等到整个HTML文档解析完成之后,才开始构建渲染树和确定布局。在不断接收和处理网络层的请求内容时,渲染引擎会将部分内容解析并显示出来。
Dom更新涉及到的东西很多,不同的Dom操作会引起不同的页面变化,Repain 和 Reflow
Reflow 的成本比 Repaint 的成本高得多的多。DOM Tree 里的每个结点都会有 reflow 方法,一个结点的 reflow 很有可能导致子结点,甚至父点以及同级结点的 reflow。在一些高性能的电脑上也许还没什么,但是如果 reflow 发生在手机上,那么这个过程是非常痛苦和耗电的。
所以,下面这些动作有很大可能会是成本比较高的。
当你增加、删除、修改 DOM 结点时,会导致 Reflow 或 Repaint。当你移动 DOM 的位置,或是搞个动画的时候。当你修改 CSS 样式的时候。当你 Resize 窗口的时候(移动端没有这个问题),或是滚动的时候。当你修改网页的默认字体时。注:display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,因为没有发现位置变化。
因为 document.getElementsByClassName 返回的是一个HTMLCollection类数组对象集合,这个集合是一个动态的集合,只要有一个节点发生变化,DOM都会重新渲染,liArr也会重新取值;一开始的 liArr 是 [red0, red1, red2, red3, red4];当 i = 0时,第一个变成green, 那么liArr就变成了[red1, red2, red3, red4], 原来的第二个red变成了第一个,依次类推,每个red向前移了一位;当 i = 1时,这时的 liArr[1]即red2是最初的liArr中的liArr[2], red1被跳过了,所以颜色没变;依次类推;
document.getElementsByClassName
[red0, red1, red2, red3, red4]
[red1, red2, red3, red4]
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
代码自上而下执行,照你的代码是一开始
className是red,执行到for循环的时候,更新className为green。写成这样你就明白了
这是document.getElementsByClassName和document.querySelectorAll的返回值不同造成的,W3C规定:前者的返回值是一个动态的 Node List,后者返回的是一个静态的 Node List,类似于快照。https://www.zhihu.com/questio...
querySelectorAll返回的元素集合中的元素是非实时的,这就是这个问题最关键之处,也是与getElement...系列的最大区别。注意这个字眼“实时”。
注:这是一个渐进的过程。渲染引擎不会等到整个HTML文档解析完成之后,才开始构建渲染树和确定布局。在不断接收和处理网络层的请求内容时,渲染引擎会将部分内容解析并显示出来。
Dom更新涉及到的东西很多,不同的Dom操作会引起不同的页面变化,Repain 和 Reflow
所以,下面这些动作有很大可能会是成本比较高的。
当你增加、删除、修改 DOM 结点时,会导致 Reflow 或 Repaint。
当你移动 DOM 的位置,或是搞个动画的时候。
当你修改 CSS 样式的时候。
当你 Resize 窗口的时候(移动端没有这个问题),或是滚动的时候。
当你修改网页的默认字体时。
注:display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,因为没有发现位置变化。
因为
document.getElementsByClassName返回的是一个HTMLCollection类数组对象集合,这个集合是一个动态的集合,只要有一个节点发生变化,DOM都会重新渲染,liArr也会重新取值;一开始的 liArr 是
[red0, red1, red2, red3, red4];当 i = 0时,第一个变成green, 那么liArr就变成了
[red1, red2, red3, red4], 原来的第二个red变成了第一个,依次类推,每个red向前移了一位;当 i = 1时,这时的 liArr[1]即red2是最初的liArr中的liArr[2], red1被跳过了,所以颜色没变;
依次类推;