按类名获取所有元素并更改ClassName

gmu*_*ent 26 javascript

我想要...

  1. 扫描文档以查找具有特定类名的所有元素
  2. 在该元素的innerHTML上执行一些关键功能
  3. 更改该元素的类名,以便如果我稍后再进行一次扫描,则不会重做该元素

我认为这段代码可以工作,但由于某种原因它在第一个实例之后打破了循环,并且元素的类名永远不会改变.没有框架请.

function example()
{
    var elementArray;

    elementArray = document.getElementsByClassName("exampleClass");

    for(var i = 0; i < elementArray.length; i++)
    {
        // PERFORM STUFF ON THE ELEMENT
        elementArray[i].setAttribute("class", "exampleClassComplete");
        alert(elementArray[i].className);
    }   
}
Run Code Online (Sandbox Code Playgroud)

编辑(最终答复) - 这是最终产品以及我如何在我的网站中实施@ cHao的解决方案.目标是在页面上抓取各种时间戳并将其更改为时间.谢谢大家的帮助,我从这个问题中学到了很多东西.

function setAllTimeAgos()
{
    var timestampArray = document.getElementsByClassName("timeAgo");

    for(var i = (timestampArray.length - 1); i >= 0; i--)
    {
        timestampArray[i].innerHTML = getTimeAgo(timestampArray[i].innerHTML);
        timestampArray[i].className = "timeAgoComplete";
    }
}
Run Code Online (Sandbox Code Playgroud)

Poi*_*nty 14

问题是返回给你的NodeList是"实时" - 它会随着你改变类名而改变.也就是说,当您更改第一个元素上的类时,列表会立即缩短一个元素.

试试这个:

  while (elementArray.length) {
    elementArray[0].className = "exampleClassComplete";
  }
Run Code Online (Sandbox Code Playgroud)

(没有必要使用setAttribute()设置"类"值 - 只需更新"className"属性.setAttribute()在旧版本的IE中使用无论如何都无法工作.)

或者,将NodeList转换为普通数组,然后使用索引迭代:

  elementArray = [].slice.call(elementArray, 0);
  for (var i = 0; i < elementArray.length; ++i)
    elementArray[i].className = "whatever";
Run Code Online (Sandbox Code Playgroud)

正如评论中所指出的,这具有不依赖于NodeList对象的语义的优点.(另请注意,再次感谢评论,如果您需要在旧版本的Internet Explorer中使用它,则必须编写显式循环以将NodeList中的元素引用复制到数组中.)


cHa*_*Hao 8

大多数返回元素列表的DOM函数返回NodeList而不是数组.最大的区别是NodeList通常是实时的,这意味着更改文档可能会导致节点神奇地出现或消失.这可能导致节点移动一点,并抛出一个不考虑它的循环.

但是,您可以简单地向后循环返回列表,而不是将列表转换为数组或其他任何内容.

function example()
{
    var elements = document.getElementsByClassName("exampleClass");

    for(var i = elements.length - 1; i >= 0; --i)
    {
        // PERFORM STUFF ON THE ELEMENT
        elements[i].className = "exampleClassComplete";

        // elements[i] no longer exists past this point, in most browsers
    }   
}
Run Code Online (Sandbox Code Playgroud)

NodeList中的活跃度也不会在这一点没关系,因为从它删除的唯一要素将是那些以后你目前所在的一个.出现在它之前的节点不会受到影响.