首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >JavaScript中的什么机制会导致DOM或CSSStyleDeclaration中的更改触发页面的重绘?

JavaScript中的什么机制会导致DOM或CSSStyleDeclaration中的更改触发页面的重绘?
EN

Stack Overflow用户
提问于 2013-05-04 20:01:24
回答 2查看 184关注 0票数 2

我认为我们理所当然地认为,每当我们更改DOM元素的属性或其CSSStyleDeclation对象的属性时,页面都会被重绘:

http://jsfiddle.net/peqtL/

代码语言:javascript
代码运行次数:0
运行
复制
document.getElementById("foo").innerHTML = "bar";
document.getElementById("foo").style.padding = "30px";

但是仔细想想,.style返回一个CSSStyleDeclaration对象,而padding返回一个属性。现在我们只需设置一个属性,那么如何触发并使页面看起来不同呢?

我在想,这是不是经典的"Observer Pattern",页面渲染器注册每个DOM元素和CSSStyleDeclaration对象,每当属性改变时,通知渲染器重新绘制页面的一部分?

或者,即使我们更改了某些内容,整个页面也会受到影响:例如,z-index将影响自身和所有兄弟节点的“覆盖”顺序,因此我们需要重新绘制父节点并向下绘制树,或者如果元素具有position: relativeposition: absolute,它可能会影响页面上的任何元素,因此需要重新绘制整个页面。因此,换句话说,渲染器可能不需要向每个DOM元素及其CSSStyleDeclaration对象注册。渲染器只需要注册顶级DOM对象( document<html>标记元素,它是document.documentElement,一个简单的实现是,对其属性或其后代的属性的任何更改,然后通知渲染器重新绘制整个页面。只要我们简单地获取属性的值,就不需要通知渲染器重新绘制页面。

这个“观察者模式”是DOM和JavaScript引擎的内部模式--也就是说,我们不能真正接触或知道它是如何在底层完成的?

我知道它的实现应该是隐藏的,对于使用超文本标记语言和JavaScript的用户来说是未知的,但从编程的角度来看,我希望知道作为软件系统的一部分,什么是一种实用的实现方式。

EN

回答 2

Stack Overflow用户

发布于 2013-05-21 23:26:10

实现此模式的一个好方法是使用css类。您应该避免修改每个HTML元素的DOM特性。若要修改HTML元素集的可视方面或添加新类,请执行以下操作。在下面的示例中,可以看到一个简单的示例:

代码语言:javascript
代码运行次数:0
运行
复制
    //html
    First name: <input type="text" id="fmame" class="mandatory">
    Last name:  <input type="text" id="lname" class="mandatory" value="Blablabla">

    //javascript
    var inputs = $("input");
    for (var i = 0, j = inputs.length; i < j; i++) {
        if (inputs[i].className === 'mandatory' && inputs[i].value === '')
            inputs[i].className += ' error';
    }

    //css
    .error {
        background-color: red;
    }
票数 0
EN

Stack Overflow用户

发布于 2015-02-19 10:10:12

观察者模式

似乎所有的布局引擎(Gecko、Trident和WebKit)都在DOM (according to this doc)上实现侦听器,这意味着它们实现了Observer pattern。实际上,每个节点都有一个附加的侦听器。

According to a certain Lindsey Simon,更新可以在任何方向触发回流,直到树上的任何端点,但布局引擎尝试尽可能减少回流和重绘计算。我会解释..。

www-archive.mozilla.org中,Gecko调用reflow有几个原因,每个原因都有不同的计算结果,包括InitialResize (相当明显)。这里相关的是incremental

增量回流

当脚本操作DOM或资源已完成异步加载(如图像)时的...occurs。Gecko将此称为“增量”,因为它试图“尽可能多地重用现有状态”(source)。当您修改DOM节点时,监听程序会自动向异步队列添加一个回流请求。为了优化队列的评估,Gecko将"coalesce",或者在共享一个目标的队列中组合类似的回流请求。不再相关的回流请求被删除(例如,如果目标帧被删除)。

高效的DOM操作

有一些方法可以明确地避免在脚本中触发不必要的回流。

在将document fragments上的

  • 操作添加到DOM节点之前,它们不会触发回流。display:none
  • 节点在更改其显示类型之前不会触发回流,即使您通过脚本对对象执行样式更改也是如此。
  • 如果要执行有效的动画,position:absolute不会向其父级发出回流,因为它已从流中删除。<代码>H224<代码>F225

请注意,从DOM读取属性还可以强制队列求值,因此信息是准确的。

我希望这是有用的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16374053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档