我只想将一个类名改为另一个。
我尝试过使用
document.getElementsByClassName("current").setAttribute("class", "none");
但它不起作用。我是javascript的新手。
答案 0 :(得分:22)
document.getElementsByClassName
会返回HTMLCollection
,而不只是一个元素数组。这意味着该集合是实时的,因此在这种特定情况下,它保留了始终使用“current”类保持所有元素的要求。
巧合的是,您正在移除集合所依赖的class
,因此更新了集合。如果您在循环中设置value
属性(例如),那将完全不同 - 集合不会受到影响,因为class
“当前”未被删除。如果您添加类(例如el.className += " none";
),情况也会完全不同,但事实并非如此。
来自MDN文档的精彩描述:
HTML DOM中的HTMLCollections正在运行;当基础文档发生变化时,它们会自动更新。
克服所有混乱局面的一个简单方法是向后循环。
var els = document.getElementsByClassName('current'),
i = els.length;
while (i--) {
els[i].className = 'none';
}
DEMO: http://jsfiddle.net/fAJgT/
(演示中的代码有setTimeout
,因此您可以先看到原始的边框颜色,然后在1.5秒后看到它会发生变化)
这是有效的,因为它修改了集合中的最后一项 - 当它被修改(并自动删除)时,移动到它之前的项目。因此它不会受到自动删除的任何后果。
另一种设置是做同样的事情:
for (i = els.length; i >= 0; i--) {
另一个答案让我意识到你可以继续操作找到的第一个项目。当您删除特定类时,该元素将从集合中删除,因此您可以保证第一个项始终是集合中的新项。因此,检查length
属性应该是一个安全的检查条件。这是一个例子:
var els = document.getElementsByClassName('current');
while (els.length) {
els[0].className = 'none';
}
DEMO: http://jsfiddle.net/EJLXe/
这基本上是说“虽然集合中仍有项目,但修改第一个(修改后将删除)”。我真的不建议使用该方法,因为它只能专门用于最终修改集合。如果你没有删除特定类,或者使用普通数组或非实时集合(没有splice
),这将无限循环。
另一种选择是将slice
(浅拷贝)集合放入一个数组并循环通过。但我认为没有任何理由/改进。以下是一个例子:
var els = document.getElementsByClassName('current'),
sliced = Array.prototype.slice.call(els), i;
for (i = 0; i < sliced.length; i++) {
sliced[i].className = 'none';
}
DEMO: http://jsfiddle.net/LHe95/2/
最后,您可以使用document.querySelector
- 它会返回非实时NodeList
(因此您可以像平常一样循环播放),甚至也有更好的支持< / strong>在浏览器中比document.getElementsByClassName
更强。这是一个例子:
var els = document.querySelectorAll('.current'),
i;
for (i = 0; i < els.length; i++) {
els[i].className = 'none';
}
DEMO: http://jsfiddle.net/xq8Xr/
<强>参考文献:强>
document.getElementsByClassName
:https://developer.mozilla.org/en-US/docs/DOM/document.getElementsByClassName HTMLCollection
:https://developer.mozilla.org/en-US/docs/DOM/HTMLCollection slice
:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/slice querySelectorAll
:https://developer.mozilla.org/en-US/docs/DOM/Document.querySelectorAll 答案 1 :(得分:3)
document.getElementsByClassName("current")
会返回HTMLCollection
,而非HTMLElement
。您可以像访问数组一样访问列表中的元素。
以下内容将更改HTMLCollection
中第一个元素的类。
document.getElementsByClassName("current")[0].setAttribute("class", "none");
但是,您不必使用setAttribute
方法,只需设置元素的className
属性即可。
element.className = 'none';
请注意HTMLCollection
是实时的,这意味着只要该元素不再具有current
类名,该元素就会从数组中删除,以避免任何问题可以使用以下方法迭代它:
var list = document.getElementsByClassName("current");
while (list.length) {
list[0].className = 'none';
}