javascript 通过 ClassName 获取所有元素并更改 ClassName
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16777885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get All Elements By ClassName and Change ClassName
提问by gmustudent
I would like to...
我想...
- Scan the document for all elements that have a certain class name
- Perform some key functions on the innerHTML of that element
- Change the class name of that element so that if I do another scan later I don't redo that element
- 扫描文档中所有具有特定类名的元素
- 对该元素的innerHTML 执行一些关键功能
- 更改该元素的类名,以便以后再扫描时不会重做该元素
I thought this code would work but for some reason it breaks the loop after the first instance and the element's class names are never changed. No frameworks please.
我认为这段代码可以工作,但由于某种原因,它在第一个实例之后中断了循环,并且元素的类名永远不会改变。请不要框架。
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);
}
}
EDIT (FINAL ANSWER)-- Here is the final product and how I have implemented @cHao's solution within my site. The objective was to grab an assortment of timestamps on the page and change them to time ago. Thank you all for your help, I learned a ton from this question.
编辑(最终答案)——这是最终产品以及我如何在我的网站中实施@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";
}
}
采纳答案by Pointy
The problem is that the NodeList returned to you is "live" - it changes as you alter the class name. That is, when you change the class on the first element, the list is immediately one element shorter than it was.
问题是返回给您的 NodeList 是“实时”的——它会随着您更改类名而发生变化。也就是说,当您更改第一个元素的类时,列表立即比原来短一个元素。
Try this:
试试这个:
while (elementArray.length) {
elementArray[0].className = "exampleClassComplete";
}
(There's no need to use setAttribute()
to set the "class" value - just update the "className" property. Using setAttribute()
in old versions of IE wouldn't work anyway.)
(不需要用来setAttribute()
设置“class”值——只需更新“className”属性。setAttribute()
在旧版本的 IE 中使用无论如何都行不通。)
Alternatively, convert your NodeList to a plain array, and then use your indexed iteration:
或者,将 NodeList 转换为普通数组,然后使用索引迭代:
elementArray = [].slice.call(elementArray, 0);
for (var i = 0; i < elementArray.length; ++i)
elementArray[i].className = "whatever";
As pointed out in a comment, this has the advantage of not relyingon the semantics of NodeList objects. (Note also, thanks again to a comment, that if you need this to work in older versions of Internet Explorer, you'd have to write an explicit loop to copy element references from the NodeList to an array.)
正如评论中指出的那样,这具有不依赖NodeList 对象语义的优点。(还要注意,再次感谢评论,如果您需要它在旧版本的 Internet Explorer 中工作,您必须编写一个显式循环来将元素引用从 NodeList 复制到数组。)
回答by cHao
Most DOM functions that return a list of elements, return a NodeList rather than an array. The biggest difference is that a NodeList is typically live, meaning that changing the document can cause nodes to magically appear or disappear. That can cause nodes to move around a bit, and throw off a loop that doesn't account for it.
大多数返回元素列表的 DOM 函数返回的是 NodeList 而不是数组。最大的区别是 NodeList 通常是live,这意味着更改文档会导致节点神奇地出现或消失。这可能会导致节点稍微移动,并抛出一个不考虑它的循环。
Rather than turning the list into an array or whatever, though, you could simply loop backwards on the list you get back.
但是,您可以简单地在返回的列表上向后循环,而不是将列表转换为数组或其他任何内容。
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
}
}
The liveness of a NodeList won't matter at that point, since the only elements removed from it will be the ones afterthe one you're currently on. The nodes that appear before it won't be affected.
NodeList中的活跃度不会不管在这一点上,因为从它删除的唯一要素将是那些以后你目前是我的唯一。在它之前出现的节点不会受到影响。
回答by Frederik.L
Another approach could be to use a selector:
另一种方法是使用选择器:
var arr = document.querySelectorAll('.exampleClass');
for (var i=0;i<arr.length;i++) {
arr.innerHTML = "new value";
}
Although it's not compatible with older browsers, it can do the trick as well if the webcontent is for modern browsers.
虽然它与旧浏览器不兼容,但如果 web 内容适用于现代浏览器,它也可以做到这一点。
回答by Xotic750
Another possibility, which should also be cross-browser, use a hand taylored getElementsByClassName which returns a fixed node list as an array. This should support from IE5.5 and upwards.
另一种可能性,也应该是跨浏览器的,使用手工定制的 getElementsByClassName ,它将固定节点列表作为数组返回。这应该支持 IE5.5 及更高版本。
function getElementsByClassName(node, className) {
var array = [],
regex = new RegExp("(^| )" + className + "( |$)"),
elements = node.getElementsByTagName("*"),
length = elements.length,
i = 0,
element;
while (i < length) {
element = elements[i];
if (regex.test(element.className)) {
array.push(element);
}
i += 1;
}
return array;
}
回答by Thiago Delgado
You can also, use 2 arrays, push data into the first array, then do what you need to do [like changing element's class]:
您还可以使用 2 个数组,将数据推送到第一个数组中,然后执行您需要执行的操作 [例如更改元素的类]:
function example()
{
var elementArray=[];
var elementsToBeChanged=[];
var i=0;
elementArray = document.getElementsByClassName("exampleClass");
for( i = 0; i < elementArray.length; i++){
elementsToBeChanged.push(elementArray[i]);
}
for( i=0; i< elementsToBeChanged.length; i++)
{
elementsToBeChanged[i].setAttribute("class", "exampleClassComplete");
}
}