获取具有特定CSS类的HTML文档中的所有元素
什么是最好的方式来获得一个具有特定的CSS类使用JavaScript的HTML文档中的所有元素的数组?
现在没有像jQuery这样的javascript框架,我可以循环所有的元素,并自己手动检查它们。 我希望有一些更优雅的东西。
下面的答案现在推四年了,所以值得注意的是本机浏览器对getElementsByClassName()
支持已经变得更好了。 但是,如果您必须支持旧浏览器,那么…
使用一个已经写好的。 大多数主要的JS库包含一种或另一种forms,但如果你不使用其中一种,那么我可以推荐Robert Nyman的优秀实现:
http://code.google.com/p/getelementsbyclassname/
http://www.robertnyman.com/2008/05/27/the-ultimate-getelementsbyclassname-anno-2008/
有太多的方法可以使这个(概念上简单的)例程变得缓慢,并且错误地certificate自己的实现在这个时候是合理的。
1)获取文档中的所有元素(document.getElementsByTagName('*'))
2)对每个元素的元素的className属性进行正则expression式匹配
你可以包含一个getElementsByClass函数,或者你可以使用一个jQueryselect器 。
更新: @ Shog9提到的实现可能比上面更好。
只是做了一些跟进,我把代码放在Shog9发布的Robert Nyman实现上,但是离开了他的确切版本,有三个原因:
- 他允许你select一个根元素和标签types来过滤你的结果。 我不需要这个function,所以通过删除它,我能够显着简化代码。
- 他的代码所做的第一件事是看看这个函数是否已经存在,如果是的话,他还是提供自己的实现。 这似乎…奇怪。 我知道他正在添加function的原始,但又一次:我没有使用这些function。
- 我想要一点额外的语法糖 – 能够调用它,就像我将调用
document.getElementById()
或document.getElementsByTagName()
。
请注意,我仍然主要依靠他的代码。 他的JavaScript技能显然远远超出了我自己的。 我确实试图分解出一些冗余的variables,但这是关于它的。
考虑到这一点,下面是我最终的结果( 似乎在IE6,IE7,Firefox3和Chrome 的最后看到新的说明 ):
if (!document.getElementsByClassName) document.getElementsByClassName = function (className) { var classes = className.split(" "); var classesToCheck = ""; var returnElements = []; var match, node, elements; if (document.evaluate) { var xhtmlNamespace = "http://www.w3.org/1999/xhtml"; var namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace:null; for(var j=0, jl=classes.length; j<jl;j+=1) classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]"; try { elements = document.evaluate(".//*" + classesToCheck, document, namespaceResolver, 0, null); } catch(e) { elements = document.evaluate(".//*" + classesToCheck, document, null, 0, null); } while ((match = elements.iterateNext())) returnElements.push(match); } else { classesToCheck = []; elements = (document.all) ? document.all : document.getElementsByTagName("*"); for (var k=0, kl=classes.length; k<kl; k+=1) classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)")); for (var l=0, ll=elements.length; l<ll;l+=1) { node = elements[l]; match = false; for (var m=0, ml=classesToCheck.length; m<ml; m+=1) { match = classesToCheck[m].test(node.className); if (!match) break; } if (match) returnElements.push(node); } } return returnElements; }
更新:
关于这个的一个新的说明。 我已经重读了原始实现的注释,现在我明白了,在现有的浏览器有自己的实现的情况下,我的代码可能会崩溃,因为默认实现会返回一个nodelist,返回一个数组。 这包括最近的Firefox和Safari浏览器,以及Opera浏览器。 大部分时间都不重要,但在某些情况下可以。 这解释了上面列表中的项目#2。
这意味着尽pipe我的代码在技术上无处不在,但是在不同的地方可能会导致细微差别(读:难以debugging),这并不好。 我应该解决这个问题,要么返回一个nodelist或覆盖提供的方法返回一个数组(这是原来的)。 前者可能会更简单,但后者会更好 。
但是,目前它在本地Intranet环境中工作(几乎所有的IE),所以暂时我将把修复作为练习给读者。
如果使用框架,他们都使用CSSselect器进行select。 除此以外。
var getElementsByClassName = function(cls, sc){ //Init var elements, i, results = [], curClass; //Default scope is document sc = sc || document; //Get all children of the scope node elements = sc.getElementsByTagName('*'); for( i=0; i < elements.length; i++ ){ curClass = elements[i].getAttribute('class'); if(curClass != null){ curClass = curClass.split(" "); for( j=0; j < curClass.length; j++){ if(curClass[j] === cls){ results.push( elements[i] ); break; } } } } return results; };
现在就写出来,只为你。 :)随意使用。
使用jQuery ,它不能更方便。
$(“。theclass”)或$(“。theclass”),makeArray()如果你想要一个本地JS数组
请记住,至lessFF3已经有一个本地实现getElementsByClassName afaik。
如果你要实现你自己的解决scheme,也许你应该尝试find一个xpath解决scheme,因为所有的现代浏览器都具有对xpath的本地支持。
@ shog9,@ user28742,@bdukes – 我正在做一些模块化的事情(自定义字段定义)在SharePoint的自定义开发,我希望可以在许多网站重复使用。
由于我不能提前知道,如果任何给定的SharePoint网站将有jQuery或任何其他库可用 – 我仍然需要写在原始JavaScript的东西,所以我可以有一定程度的信心,我的function试图实现将站在它自己的。
感谢德米特里为您的具体实施。 我的目的足够短。
在最近的其他工作中,我不得不修改一个电子商务商店(我的客户select),而我试图将jQuery安装到其中的一些尝试实际上与他们之前操作的任何定制库冲突。 我本来可以坚持下去,并且将jQuery实现到他们专有的系统中,或者更快地实现,只需要写一些好的javascript。
Libaries并不总是最好的答案!!!!!!!!!!!!!!!!
(我比我的祖母更爱jQuery)
没有像CSS类那样的东西。 CSS有规则集和select器(包括类select器)。
你的意思是一个HTML类吗? 通常的方法是循环遍历文档中的每个元素( using document.getElementsByTagName('*')
(为了提高效率,如果知道该类将只应用于特定types的元素,则使用特定的标记名称) (注意属性包含空格分隔的类名称列表,而不是单个类名称)。
许多库(如jQuery或YUI )都具有简单的function。
你的意思是一个CSSselect器? 这变得越来越复杂,转向图书馆几乎肯定是在这里做的正确的事情。 再一次,jQuery或YUI是不错的select。
如果你想为文档中所有具有相同id的元素做些什么。 虽然简单但有时不介意给绿色信号
var x = document.getElementById(elementid); while(x){ document.removechild(x); x = document.getElementById(elementid); }