css - JavaScript DOM操作, 啥时候同步更新?
高洛峰
高洛峰 2017-04-11 13:04:25
[JavaScript讨论组]



    
    Title
    



  • 哈哈0
  • 哈哈1
  • 哈哈2
  • 哈哈3
  • 哈哈4

感谢各位指点,找到问题答案了.
后面是一个小结:
https://icbd.github.io/wiki/w...

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(4)
PHPz

代码自上而下执行,照你的代码是一开始classNamered,执行到for循环的时候,更新classNamegreen

写成这样你就明白了

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)将每个节点绘制出来。

注:这是一个渐进的过程。渲染引擎不会等到整个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,因为没有发现位置变化。

PHP中文网

因为 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被跳过了,所以颜色没变;
依次类推;

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号