Joe*_*orn 38 html javascript css
使用javascript使用特定CSS类获取html文档中所有元素数组的最佳方法是什么?
现在没有像jQuery这样的javascript框架,我可以循环所有元素并自己手动检查它们.我希望有一些更优雅的东西.
Chr*_*ald 38
1)获取文档中的所有元素(document.getElementsByTagName('*'))
2)对每个元素的元素的className属性执行正则表达式匹配
Sho*_*og9 36
下面的答案正在推动四岁,所以这是值得注意的是,原生浏览器支持getElementsByClassName()已经得到了很多更好.但如果您必须支持旧浏览器,那么......
使用已经写过的.大多数主要的JS库都包含某种形式的库,但如果您不使用其中一种,那么我可以推荐Robert Nyman的优秀实现:
http://code.google.com/p/getelementsbyclassname/
http://www.robertnyman.com/2008/05/27/the-ultimate-getelementsbyclassname-anno-2008/
有太多方法可以使这个(概念上简单的)例程缓慢而且错误,以证明此时编写自己的实现是正确的.
为了做一些跟进,我将我的代码基于Shog9发布的Robert Nyman实现,但是从他的确切版本中略微偏离了三个原因:
document.getElementById()或者那样称呼它document.getElementsByTagName().请注意,我仍然主要依赖他的代码.他的javascript技能显然远远超出了我自己.我确实尝试将一些冗余变量分解出来,但这就是它.
考虑到这一点,这就是我最终得到的结果(似乎在IE6,IE7,Firefox 3和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;
}
Run Code Online (Sandbox Code Playgroud)
更新:
关于此的一个新注释.我已经重新阅读了原始实现的注释,现在我明白,在现有浏览器拥有自己的实现的情况下,我的代码可能会失败,因为默认实现返回一个nodelist,返回一个数组.这包括更新的firefox和safari,以及opera浏览器.大部分时间都无关紧要,但在某些情况下却可以.这解释了上面列表中的第2项.
这意味着虽然我的代码在技术上可以在任何地方工作,但它可能会导致在不同的地方产生微妙的不同(读取:难以调试)行为,这并不好.我应该修复此问题,或者返回一个nodelist或覆盖提供的方法以返回一个数组(这是原始的).可能前者会更简单,但后者会更好.
但是,它现在正在本地内部网环境中工作(几乎所有的IE),所以暂时我会把修复程序作为练习给读者.
如果使用框架,它们都可以使用CSS选择器进行选择.除此以外.
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;
};
Run Code Online (Sandbox Code Playgroud)
只是为了你而现在写的.:)随意使用.
| 归档时间: |
|
| 查看次数: |
97710 次 |
| 最近记录: |