我试过使用
document.getElementsByClassName(“current”).setAttribute(“class”,“none”);
但它不行.我是javascript的新手.
解决方法
document.getElementsByClassName返回一个HTMLCollection,而不仅仅是一个元素数组.这意味着收集是活的,所以在这种具体情况下,它保留了它将始终保持类“current”的所有元素的要求.
巧合的是,您正在删除集合所依赖的类,因此更新集合.如果您在循环中设置了value属性(例如),那么它将是完全不同的 – 集合不会受到影响,因为类“current”未被删除.如果你添加一个类,例如el.className =“none”,那么也是完全不一样的,但事实并非如此.
MDN文档的一个很好的描述:
HTMLCollections in the HTML DOM are live; they are automatically updated when the underlying document is changed.
方法1
克服所有这种混乱的简单方法是循环向后.
var els = document.getElementsByClassName('current'),i = els.length; while (i--) { els[i].className = 'none'; }
(演示中的代码有一个setTimeout,所以你可以先看到原始的边框颜色,然后在1.5秒后看到它改变)
这是因为它修改了集合中的最后一个项目 – 当它被修改(并自动删除)时,移动到该项目之前.所以它不会遭受自动删除的任何后果.
一个替代的设置,做同样的事情是:
for (i = els.length; i >= 0; i--) {
方法2
另一个答案让我意识到,你可以继续操作第一个找到的项目.当您删除特定的类时,元素将从集合中删除,因此您可以确保第一个项目始终是集合中的新项目.因此,检查长度属性应该是一个安全的检查条件.以下是一个例子:
var els = document.getElementsByClassName('current'); while (els.length) { els[0].className = 'none'; }
这基本上是说“在收藏中仍然有项目,修改第一个(修改后将删除)”.我真的不会建议使用这种方法,因为它只有特别是因为你最终修改集合.如果您不删除特定类,或者使用正常数组或非活动集合(无拼接),这将无限循环.
方法3
另一个选择是将集合(浅层拷贝)成一个数组并循环遍历正常.但是我没有看到任何理由/改进.这里有一个例子:
var els = document.getElementsByClassName('current'),sliced = Array.prototype.slice.call(els),i; for (i = 0; i < sliced.length; i++) { sliced[i].className = 'none'; }
演示:http://jsfiddle.net/LHe95/2/
方法4
最后,您可以使用document.querySelector – 它返回一个非活动的NodeList(因此您可以像常规一样循环),甚至比在document.getElementsByClassName中更好地支持浏览器.以下是一个例子:
var els = document.querySelectorAll('.current'),i; for (i = 0; i < els.length; i++) { els[i].className = 'none'; }
参考文献:
> document.getElementsByClassName:https://developer.mozilla.org/en-US/docs/DOM/document.getElementsByClassName
> HTMLCollection:https://developer.mozilla.org/en-US/docs/DOM/HTMLCollection
>切片:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/slice
> querySelectorAll:https://developer.mozilla.org/en-US/docs/DOM/Document.querySelectorAll