如何在Javascript中快速更新许多元素的类?

时间:2018-03-09 17:17:15

标签: javascript performance dom

我在页面上有几千个元素,按下按钮后应该更改CSS类。 目前我有以下js代码:

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

在IE中,这需要将近20秒。我做了一些分析,看起来.className操作只需要半毫秒;与垃圾收集一起使用它需要很长时间。我不确定.className是否导致重排。

无论哪种方式,我怎样才能比现在更快地完成这项任务?

1 个答案:

答案 0 :(得分: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的示例,并在按钮上单击它随机切换每个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>