【发布时间】:2014-06-07 06:19:20
【问题描述】:
从https://developers.google.com/speed/articles/javascript-dom得到这个
据我了解,添加/删除元素会导致重排。换班也是如此。但在解决方案中,您要附加 和 删除,因此导致回流次数是问题代码的 2 倍。当然,并不是所有的回流都是平等的,那么类名更改回流比追加/删除回流更昂贵吗?我遗漏了什么使解决方案代码比问题代码更高效?
这种模式让我们可以创建多个元素并将它们插入到 DOM 触发单个回流。它使用一种叫做 文档片段。我们在 DOM 之外创建一个 DocumentFragment(所以 它是不合时宜的)。然后我们创建并添加多个元素 这。最后,我们将 DocumentFragment 中的所有元素移动到 DOM 但会触发一次回流。
问题
让我们创建一个函数来更改所有的 className 属性 元素内的锚点。我们可以通过简单的迭代来做到这一点 通过每个锚点并更新它们的 href 属性。问题 也就是说,这可能会导致每个锚点的回流。
function updateAllAnchors(element, anchorClass) { var anchors = element.getElementsByTagName('a'); for (var i = 0, length = anchors.length; i < length; i ++) { anchors[i].className = anchorClass; } }解决办法
为了解决这个问题,我们可以从 DOM 中移除元素,更新 所有锚点,然后将元素插入到原来的位置。帮助 实现这一点,我们可以编写一个可重用的函数,它不仅删除 来自 DOM 的元素,但也返回将插入的函数 元素回到原来的位置。
/** * Remove an element and provide a function that inserts it into its original position * @param element {Element} The element to be temporarily removed * @return {Function} A function that inserts the element into its original position **/ function removeToInsertLater(element) { var parentNode = element.parentNode; var nextSibling = element.nextSibling; parentNode.removeChild(element); return function() { if (nextSibling) { parentNode.insertBefore(element, nextSibling); } else { parentNode.appendChild(element); } }; }现在我们可以使用这个函数来更新元素内的锚点 那是不合流的,只有当我们移除 元素以及当我们插入元素时。
function updateAllAnchors(element, anchorClass) { var insertFunction = removeToInsertLater(element); var anchors = element.getElementsByTagName('a'); for (var i = 0, length = anchors.length; i < length; i ++) { anchors[i].className = anchorClass; } insertFunction(); }
【问题讨论】:
标签: javascript html css dom