【问题标题】:How to quickly update the classes of many elements in Javascript?如何快速更新Javascript中许多元素的类?
【发布时间】:2018-08-18 07:54:45
【问题描述】:

我在一个页面上有几千个元素,它们的 CSS 类应该在按下按钮时更改。 目前我的js代码如下:

for each (var id in list) {
    var element = document.querySelector('[data-id="' + id + ']');
    element.className = 'myClass';
}

在 IE 中,这需要将近 20 秒。我做了一些分析,似乎 .className 操作需要半毫秒;这与垃圾收集一起使得它需要这么长时间。我不确定 .className 是否会导致回流。

无论如何,我怎样才能比现在更快地完成这项任务?

【问题讨论】:

  • 什么for each???
  • 它似乎已被弃用。替换为 for (x of y)
  • 它从未存在过
  • 在 Javascript 1.6 中引入,不知道何时弃用:developer.mozilla.org/en-US/docs/Web/JavaScript/…
  • 哦,对了,这从来都不是语言的一部分,我很惊讶它居然在规范中

标签: javascript performance dom


【解决方案1】:

我会让 CSS 完成所有艰苦的工作..

只要有某种父类,向它添加一个类并让你的 CSS 以它为目标。

例如。

document.querySelector("button").onclick = function () {
  document.body.classList.toggle("button-clicked");
}
[data-id] {
  background-color: yellow;
}

.button-clicked [data-id] {
  background-color: pink;
}
<div data-id="1">One</div>
<div data-id="2">Two</div>
<div data-id="3">Three</div>
<div data-id="4">Four</div>
<div data-id="5">Five</div>

<button>Click Me</button>

如果只做这个 CSS 不是一个选项,更新 DOM 的最佳方法是分离它。这是一个创建 10,000 个 div 的示例,在按钮上单击它会随机切换每个选定的类,但在此之前会暂时将它们与 DOM 分离,然后在翻转类后重新附加。

var container = document.querySelector(".container");

function addLine (txt) {
  var div = document.createElement("div");
  div.innerText = txt;
  div.classList.add("line");
  container.appendChild(div);
}

for (var l = 1; l <= 10000; l += 1) {
  addLine("This is Line " + l + ", and some extra text");
}

document.querySelector("button").onclick = function () {
  //temporally remove from DOM 
  container.parentNode.removeChild(container);  
  //all DOM methods here on conatiner should now be fast
  //as there is no UI updates required..
  var lines = container.querySelectorAll(".line");
  for (var l = 0; l < lines.length; l ++) {
    var e = lines[l];
    if (Math.random() > 0.5)
      e.classList.toggle("selected");
  };
  //Ok done, lets now put it back into the DOM
  document.body.appendChild(container); 
}
.line {
  background-color: yellow;
}

.line.selected {
  background-color: red;
}
<button>toggle class</button>

<div class="container">
</div>

【讨论】:

  • 我真的很喜欢这个答案,但是,如果不清楚,我很抱歉,我确实需要每个元素都有自己的类。这是因为每个元素都可以通过不同的操作自行切换。
  • 好的,更新的答案也可以使用分离的 DOM 方法。
  • 嗨,Keith,我真的很感谢你再试一次。这个解决方案在 Chrome 中运行不到一秒钟,这很棒。但不幸的是,在 IE 中,我不知道需要多长时间,因为几分钟后我放弃了(尝试了几次之后)。需要注意的是,点击“Run code sn-p”并创建初始列表无论如何都很快,它是Toggle Class按钮。到目前为止,这与这方面的经验相符。
  • 事实上,在我的生产代码中,我使用分离的 div 创建结构并且它运行得很快,我什至尝试重新创建 div 并将其附加到 DOM 而不是更新 className,但它的速度较慢不管什么原因。我不明白。
  • 是的,这很奇怪.. 不幸的是我没有 IE11,我在 Win10 上并没有安装它,.. 但是在 Edge 上运行仍然非常快。嗯..你可以尝试说 100 div 开始,首先看看它是否有效,10,000 div 可能是 IE11 无法分离或不破解的东西。
猜你喜欢
  • 2015-07-14
  • 2014-03-07
  • 1970-01-01
  • 1970-01-01
  • 2016-10-01
  • 1970-01-01
  • 2010-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多