如何在更改元素可见性的同时冻结Web浏览器的重绘?

时间:2021-12-01 04:06:40

I'm by far no JS developer (in fact, hardly developer at all :) but I wanted to try to write a small Greasemonkey script to hide few elements on a certain webpage. Once I've started dabbing at it, I've decided to use jQuery, just to make it easier. Everything went well, the script is working, but now that it's ready, I've started to wonder about the details.

我到目前为止还没有JS开发人员(事实上,根本不是开发人员:)但我想尝试编写一个小的Greasemonkey脚本来隐藏某个网页上的几个元素。一旦我开始轻拍它,我决定使用jQuery,只是为了让它更容易。一切顺利,脚本正在运行,但现在已经准备就绪,我开始怀疑细节。

As a part of the script, I need to find specific element and hide it, together with previous and next of its siblings. I've ended up with not that readable, but working line:

作为脚本的一部分,我需要找到特定元素并将其与其兄弟姐妹的前一个和下一个一起隐藏起来。我最终没有那么可读,但工作线:

$('div#some-weird-box').prev().toggle(w).next().toggle(w).next().toggle(w);

My concern here is, that I'm removing three separate divs in three separate steps. This would cause browser to "repaint" the page three times, right? It's not a problem with three divs, it would probably start to matter when there are more elements. So, my question is - is there a way to tell browser "stop refreshing/redrawing the page"? If there is, I could use that, hide arbitrary number of elements, then ask browser to update the screen.

我在这里担心的是,我将在三个不同的步骤中删除三个独立的div。这会导致浏览器三次“重绘”页面,对吗?这不是三个div的问题,当有更多元素时,它可能会开始变得重要。所以,我的问题是 - 有没有办法告诉浏览器“停止刷新/重绘页面”?如果有,我可以使用它,隐藏任意数量的元素,然后要求浏览器更新屏幕。

2 个解决方案

#1


20  

Javascript execution locks the browser and you will not see a repaint until your code execution is finished. You really have nothing to worry about with this.

Javascript执行会锁定浏览器,在代码执行完成之前,您不会看到重绘。你真的没有什么可担心的。

I posted a good example of this on jsbin.com: http://jsbin.com/ecuku/edit

我在jsbin.com上发布了一个很好的例子:http://jsbin.com/ecuku/edit

Update: Often it is suggested to modify nodes outside of the DOM because modifying the DOM does cause reflows (not repaints). Reflows are when the browser has to recalculate positions and sizes of elements on your page because something has changed. While your javascript execution can cause multiple reflows, it will only cause one repaint (when your code finishes). Those reflows can be a big performance hit, but for small numbers of DOM changes (e.g. your code only has 3) it probably isn't worth the work to do make your changes outside of the page. Also, cloning a node and modifying it outside of the page before inserting it back can have unexpected consequences. For example, if you had event handlers attached they would need to be reattached to the new nodes.

更新:通常建议修改DOM之外的节点,因为修改DOM会导致重排(而不是重绘)。回流是指浏览器必须重新计算页面上元素的位置和大小,因为某些内容已发生变化。虽然你的javascript执行可以导致多次重排,但它只会导致一次重绘(当你的代码完成时)。这些回流可能是一个很大的性能损失,但对于少量的DOM更改(例如,您的代码只有3个),可能不值得做的工作在页面之外进行更改。此外,克隆节点并在插入节点之前将其修改到页面之外可能会产生意外后果。例如,如果您附加了事件处理程序,则需要将它们重新附加到新节点。

#2


2  

You can use cloneNode. After cloning you can do all manipulations over the clone and than replace original node. This will prevent your content from blinking when display:none like J-P proposed.

您可以使用cloneNode。克隆后,您可以对克隆进行所有操作,然后替换原始节点。这样可以防止您的内容在显示时闪烁:没有像J-P那样建议。

#1


20  

Javascript execution locks the browser and you will not see a repaint until your code execution is finished. You really have nothing to worry about with this.

Javascript执行会锁定浏览器,在代码执行完成之前,您不会看到重绘。你真的没有什么可担心的。

I posted a good example of this on jsbin.com: http://jsbin.com/ecuku/edit

我在jsbin.com上发布了一个很好的例子:http://jsbin.com/ecuku/edit

Update: Often it is suggested to modify nodes outside of the DOM because modifying the DOM does cause reflows (not repaints). Reflows are when the browser has to recalculate positions and sizes of elements on your page because something has changed. While your javascript execution can cause multiple reflows, it will only cause one repaint (when your code finishes). Those reflows can be a big performance hit, but for small numbers of DOM changes (e.g. your code only has 3) it probably isn't worth the work to do make your changes outside of the page. Also, cloning a node and modifying it outside of the page before inserting it back can have unexpected consequences. For example, if you had event handlers attached they would need to be reattached to the new nodes.

更新:通常建议修改DOM之外的节点,因为修改DOM会导致重排(而不是重绘)。回流是指浏览器必须重新计算页面上元素的位置和大小,因为某些内容已发生变化。虽然你的javascript执行可以导致多次重排,但它只会导致一次重绘(当你的代码完成时)。这些回流可能是一个很大的性能损失,但对于少量的DOM更改(例如,您的代码只有3个),可能不值得做的工作在页面之外进行更改。此外,克隆节点并在插入节点之前将其修改到页面之外可能会产生意外后果。例如,如果您附加了事件处理程序,则需要将它们重新附加到新节点。

#2


2  

You can use cloneNode. After cloning you can do all manipulations over the clone and than replace original node. This will prevent your content from blinking when display:none like J-P proposed.

您可以使用cloneNode。克隆后,您可以对克隆进行所有操作,然后替换原始节点。这样可以防止您的内容在显示时闪烁:没有像J-P那样建议。