0

注意:使用 3rd 方标签系统不是一个选项,因此请不要推荐。

在我的页面上,我有几个<div>s 和几个选项卡。每个 div 可以属于多个选项卡。例如,所有 div 都属于“All”选项卡,然后一些 div 属于“Today”选项卡,一些属于“Tomorrow”,等等。

我想要做的是,当用户单击“今天”选项卡时,我只想显示属于该选项卡的 div。当他单击任何其他选项卡时,前一个选项卡的 div 应该被隐藏并且所选选项卡的 div 应该显示。到目前为止,非常标准的标签行为。

然而不同的是,一个 div 可以在多个选项卡之间共享。

I was thinking that, whenever a new tab is selected, I could simply loop through all the divs of the last selected tab, hide them, and then loop through the current tab's divs and show them.

但是我想知道是否会有更有效/更少 CPU 密集型的方法。此外,如果它们在最后一个选项卡和当前选项卡之间共享,此方法将导致一些 div 被隐藏,然后立即再次淋浴。(例如:div_111 可以在今天和明天之间共享。用户点击今天,div_111 被显示。然后他点击明天,div_111 最初是隐藏的,然后才再次显示)。

有什么建议么?

4

1 回答 1

2

你要注意的是重绘。当您添加或删除一个元素时,浏览器必须弄清楚更改如何影响页面上的每个其他元素,并相应地重新定位/调整每个元素的大小。这个过程几乎总是 DOM 操作中最昂贵的部分——当然比找出哪些元素进入哪些选项卡更昂贵。

浏览器尝试优化重绘——它们尽可能少地重绘页面,有时将多个更改组合到同一个重绘中。但是,最好将事情掌握在自己手中。无论添加或删除多少个节点,您都可以确保重绘不超过两次,方法是首先从 DOM 中删除父节点,然后进行所有更改,然后重新附加它。这是一个简单的例子:

var container = document.getElementById('container'),
    buffer = document.createDocumentFragment(),
    newNodes = tabs[selection], // an array or object, generated at page load,
                                // containing all divs that show up in this tab
    i, div;
document.body.removeChild(container);
for (i = 0; div = newNodes[i]; i++) {
    buffer.appendChild(div); // if div is in container then it will be
                             // automatically removed
}
container.innerHTML = ''; // probably more efficient to remove nodes individually
container.appendChild(buffer);
document.body.appendChild(container);

根据您的布局,删除container可能会导致其下方的内容瞬间跳跃。如果您想要一个优美的外观,您可以固定container' 父级的高度或在其位置插入一个占位符container.parentNode.replaceNode().

如果您最小化重绘,那么您不应该有任何效率问题。但是,如果您仍然想调整,当然,优化您的内容插入逻辑。最简单的方法可能是将绑定到单个选项卡的内容与显示在多个选项卡中的内容分开,可能通过为每种内容类型使用不同的容器。请记住,最好的解决方案是不比它需要的更通用的解决方案。

于 2012-04-27T05:11:51.103 回答