Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/448.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中的哪种机制会导致DOM或CSSStyleDeclaration中的更改触发页面重画?_Javascript_Design Patterns_Dom_Observer Pattern - Fatal编程技术网

JavaScript中的哪种机制会导致DOM或CSSStyleDeclaration中的更改触发页面重画?

JavaScript中的哪种机制会导致DOM或CSSStyleDeclaration中的更改触发页面重画?,javascript,design-patterns,dom,observer-pattern,Javascript,Design Patterns,Dom,Observer Pattern,我认为我们只是想当然地认为,每当我们更改DOM元素的属性或其CSSStyleDeclation对象的属性时,页面都会被重新绘制: 但是仔细想想,.style返回一个CSSStyleDeclaration对象,padding返回一个属性。现在我们只需设置一个属性,它是如何触发并使页面看起来不同的呢 我在想,这是否会是经典的“”,其中页面呈现器注册每个DOM元素和CSSStyleDeclaration对象,每当属性更改时,通知呈现器重新绘制页面的一部分 或者,即使我们更改了某些内容,整个页面也会受

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

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

我在想,这是否会是经典的“”,其中页面呈现器注册每个DOM元素和
CSSStyleDeclaration
对象,每当属性更改时,通知呈现器重新绘制页面的一部分

或者,即使我们更改了某些内容,整个页面也会受到影响:例如,
z-index
将影响自身和所有同级节点的“隐藏”顺序,因此我们需要重新绘制父节点并向下绘制树,或者如果元素具有
位置:相对
位置:绝对
,该怎么办,它可能会影响页面上的任何元素,因此需要重新绘制整个页面。因此,换句话说,渲染器可能不需要向每个DOM元素及其
CSSStyleDeclaration
对象注册。渲染只需要注册顶级DOM对象(无论是
document
还是
标记元素,即
document.documentElement
,一个简单的实现是,对其属性或其后代属性的任何更改,然后通知渲染器重新绘制整个页面。只要我们获得属性的值,渲染器就不需要通知redr看这一页

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


我知道这个实现应该是隐藏的,对HTML和JavaScript的用户来说是未知的,但是从编程的角度来看,我希望知道作为软件系统的一部分,实现这个模式的一个好方法是使用css类。你应该避免修改e每个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;
    }
//html
名字:
姓氏:
//javascript
var输入=$(“输入”);
对于(变量i=0,j=inputs.length;i
观察者模式 似乎所有布局引擎(Gecko、Trident和WebKit)都在DOM()上实现侦听器,这意味着它们实现了一个。事实上,每个节点都连接了一个侦听器

,更新可以在任何方向触发回流,直到树上的任何端点,但布局引擎会尽量减少回流和重新绘制计算。我将解释

从中,Gecko调用回流有几个原因,每个原因都有不同的计算结果,包括初始调整大小(相当明显)。这里的相关原因是增量

增量回流焊 …当脚本操作DOM或资源异步加载(如映像)完成时发生。Gecko称此为“增量”,因为它尝试“尽可能重用现有状态”()。当您修改DOM节点时,侦听器会自动将回流请求添加到异步队列。为了优化对队列的评估,Gecko将“合并”,或在队列中合并共享目标的类似回流请求。不再相关的回流请求将被删除(例如,如果目标帧已移除)

高效的DOM操作 有一些方法可以显式避免从脚本中触发不必要的回流

  • 上的操作在添加到DOM节点之前不会触发回流
  • display:none
    节点在其显示类型更改之前不会触发回流,即使您从脚本对对象执行样式更改
  • 如果要执行有效的动画,
    position:absolute
    将不会向其父级发出回流,因为它已从流中取出
请注意,从DOM读取属性还可以强制执行队列计算,以便信息准确


我希望这是有用的。

你不明白设置填充如何改变页面显示?这里的键是通过什么机制被称为setter的。分配给这些属性会触发setter函数。但是页面重画是通过什么机制?你的意思是每个setter都会调用重画函数?当然。如果分配给
 样式
更改页面显示,将出现回流。我认为您不理解这个问题。OP询问浏览器的渲染引擎如何知道何时重新绘制。
    //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;
    }