getElementsByClassName遍历时出现的问题

前端语法/样式/布局 2018-09-05

前言

我们需要遍历.lyad的元素,并将其className中的lyad删掉。

最开始的做法是

var s = 'lyad'
var eles = document.querySelectorAll('.'+'s');
for (var j = 0,len=eles.length; j < len; j++) {
  eles[j].className = eles[j].className.replace(s, '')
}

没有任何问题。

查询文档以及自测,发现 getElementsByClassName 的速度比 querySelectorAll 快很多,5倍以上。

为了性能考虑,我们改为以下写法:

var eles = document.getElementsByClassName(s)
for (var j = 0,len=eles.length; j < len; j++) {
  eles[j].className = eles[j].className.replace(s, '')
}

不出意外,会报Cannot read property 'className' of undefined 错误。

观察发现,一开始 eles 为四个,在访问eles[2]的时候出错,说明此时eles.length===2,访问了一个空元素。

即, getElementsByClassName 得到的元素其对应className 被删掉的话,eles 会自动删去其元素。

做个测试:

var eles = document.getElementsByClassName('lyad')
console.log(eles.length) //4
eles[0].className = eles[0].className.replace('lyad', '')
console.log(eles.length) //3

以下写法都是ok的

var eles = document.getElementsByClassName('lyad')
while(eles.length>0){
  eles[0].className = eles[0].className.replace('lyad', '')
}

注意 eles 获取要用 getElementsByClassName 而不是 querySelectorAll 否则将导致死循环。

var eles = document.getElementsByClassName('lyad')
for (var j = 0,len=eles.length; j < len; j++) {
  eles[0].className = eles[0].className.replace('lyad', '')
}

注意 len 需要用临时变量保存,否则每次获取将会得到不同的 length 导致提前结束。

相比上一种写法更安全。


本文由 GaHingZ 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

赏个馒头吧