Javascript试图迭代getElementsByClassName

时间:2017-10-09 21:36:10

标签: javascript

我想首先说我是普通JavaScript的新手,所以如果有明显的话,我很抱歉。

当有人使用以下代码重新提交表单时,我试图删除错误。

let div = document.getElementsByClassName('error')
if (div.length > 0 ){
    console.log(div);
    console.log('Length: ' + div.length);
    for (i = 0; i <= div.length; i++){
        console.log('i= ' + i)
        let e = div[i]
        e.innerHTML = ''
        e.classList.remove('error')
    }
}

这有效,sorta,我最终得到所有其他div与错误类被改变而不是所有。

Developer Console Screenshot

2 个答案:

答案 0 :(得分:5)

.getElementsByClassName()函数返回实时 NodeList。这意味着当您更改条目上的类时,它将从列表中消失。列表的长度会减一,因此您的迭代会跳过其他所有条目。

这样做的一个好方法是只对列表中的第一件事进行操作,直到列表为空:

while (div.length) {
    let e = div[0]
    e.innerHTML = ''
    e.classList.remove('error')
}

答案 1 :(得分:1)

实时和“静态”HTMLCollections / NodeLists

旧方法.getElementsByTagName().getElementsByName().getElementsByClassName()<div>等返回DOM对象的实时集合。这意味着此集合中的任何对象(即元素,即<span>.querySelectorAll()等)(又名 HTMLCollection ,又名 NodeList )是修改或删除,或者如果添加了新对象,整个集合将立即更改。因此,在每个循环中,您实际上都有一个不同的数组(或类似数组的对象),因此结果是不断变化的值和数量组的产物。

  • 使用for返回“静态”NodeList。

  • 使用i循环,通过以下方式声明增量var(for):

    var i = 0;循环之外将其声明为:for

    OR

    let i = 0;循环内声明为:var div = document.querySelectorAll('.error'); var qty = div.length; for (let i = 0; i < qty; i++) { console.log('i= ' + i); var d = div[i]; d.innerHTML = 'GOOD'; d.classList.toggle('error', 'good'); }

演示

.as-console-wrapper.as-console-wrapper {
  transform: translateX(100%);
  max-width: 250px;
  height: 100%;
  color: blue;
  font: 400 15px/1.3 'Consolas';
}
<div class='error'>ERROR</div>
<div class='error'>ERROR</div>
<div class='error'>ERROR</div>
<div class='error'>ERROR</div>
<div class='error'>ERROR</div>
<div class='good'>GOOD</div>
<div class='error'>ERROR</div>
<div class='error'>ERROR</div>
<div class='error'>ERROR</div>
<div class='error'>ERROR</div>
{{1}}