我想我们只是想当然地认为,每当我们更改 DOM 元素的属性或其 CSSStyleDeclation 对象的属性时,页面都会被重绘:
document.getElementById("foo").innerHTML = "bar";
document.getElementById("foo").style.padding = "30px";
但是想一想,.style
返回一个CSSStyleDeclaration
对象,padding
返回一个属性。现在我们只需设置一个属性,它是如何触发并导致页面看起来不同的呢?
我在想,这会是经典的“观察者模式”吗,页面渲染器注册每个 DOM 元素和CSSStyleDeclaration
对象,每当属性更改时,通知渲染器重绘页面的一部分?
或者,是不是即使我们改变了一些东西,也会影响到整个页面:比如z-index
会影响自己和所有兄弟节点的“覆盖”顺序,所以我们需要重绘父节点并向下树,或者如果元素有position: relative
或position: absolute
,它可以影响页面上的任何元素,所以需要重绘整个页面。所以换句话说,渲染器可能不需要注册每个 DOM 元素及其CSSStyleDeclaration
对象。渲染器只需要注册顶级 DOM 对象(或者document
标签<html>
元素,即document.documentElement
一个简单的实现是,对其属性或其后代的属性进行任何更改,然后通知渲染器重绘整个页面。每当我们简单地获取属性的值时,都不需要通知渲染器来重绘页面。
而这种“观察者模式”是 DOM 和 JavaScript 引擎内部的——也就是说,我们无法真正接触或知道它是如何在底层完成的?
我知道实现应该是隐藏的,并且对于 HTML 和 JavaScript 的用户来说是未知的,但是从编程的角度来看,我希望知道作为软件系统的一部分可以实现它的实用方法是什么。