我认为我们理所当然地认为,每当我们更改DOM元素的属性或其CSSStyleDeclation对象的属性时,页面都会被重绘:
document.getElementById("foo").innerHTML = "bar";
document.getElementById("foo").style.padding = "30px";
但是仔细想想,.style
返回一个CSSStyleDeclaration
对象,而padding
返回一个属性。现在我们只需设置一个属性,那么如何触发并使页面看起来不同呢?
我在想,这是不是经典的"Observer Pattern",页面渲染器注册每个DOM元素和CSSStyleDeclaration
对象,每当属性改变时,通知渲染器重新绘制页面的一部分?
或者,即使我们更改了某些内容,整个页面也会受到影响:例如,z-index
将影响自身和所有兄弟节点的“覆盖”顺序,因此我们需要重新绘制父节点并向下绘制树,或者如果元素具有position: relative
或position: absolute
,它可能会影响页面上的任何元素,因此需要重新绘制整个页面。因此,换句话说,渲染器可能不需要向每个DOM元素及其CSSStyleDeclaration
对象注册。渲染器只需要注册顶级DOM对象( document
或<html>
标记元素,它是document.documentElement
,一个简单的实现是,对其属性或其后代的属性的任何更改,然后通知渲染器重新绘制整个页面。只要我们简单地获取属性的值,就不需要通知渲染器重新绘制页面。
这个“观察者模式”是DOM和JavaScript引擎的内部模式--也就是说,我们不能真正接触或知道它是如何在底层完成的?
我知道它的实现应该是隐藏的,对于使用超文本标记语言和JavaScript的用户来说是未知的,但从编程的角度来看,我希望知道作为软件系统的一部分,什么是一种实用的实现方式。
发布于 2013-05-21 15:26:10
实现此模式的一个好方法是使用css类。您应该避免修改每个HTML元素的DOM特性。若要修改HTML元素集的可视方面或添加新类,请执行以下操作。在下面的示例中,可以看到一个简单的示例:
//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;
}
发布于 2015-02-19 02:10:12
观察者模式
似乎所有的布局引擎(Gecko、Trident和WebKit)都在DOM (according to this doc)上实现侦听器,这意味着它们实现了Observer pattern。实际上,每个节点都有一个附加的侦听器。
According to a certain Lindsey Simon,更新可以在任何方向触发回流,直到树上的任何端点,但布局引擎尝试尽可能减少回流和重绘计算。我会解释..。
从www-archive.mozilla.org中,Gecko调用reflow有几个原因,每个原因都有不同的计算结果,包括Initial和Resize (相当明显)。这里相关的是incremental。
增量回流
当脚本操作DOM或资源已完成异步加载(如图像)时的...occurs。Gecko将此称为“增量”,因为它试图“尽可能多地重用现有状态”(source)。当您修改DOM节点时,监听程序会自动向异步队列添加一个回流请求。为了优化队列的评估,Gecko将"coalesce",或者在共享一个目标的队列中组合类似的回流请求。不再相关的回流请求被删除(例如,如果目标帧被删除)。
高效的DOM操作
有一些方法可以明确地避免在脚本中触发不必要的回流。
display:none
的position:absolute
不会向其父级发出回流,因为它已从流中删除。<代码>H224<代码>F225请注意,从DOM读取属性还可以强制队列求值,因此信息是准确的。
我希望这是有用的。
https://stackoverflow.com/questions/16374053
复制相似问题