就像在jQuery中我们可以使用$(“。classname”),javascript中也有类似的东西吗?或者如果我们没有这样的方法,那么我该如何实现呢 根据{{3}},我将遍历所有标签,然后收集所有与指定类相同的元素。
有没有更好的解决方案?
答案 0 :(得分:14)
我必须迭代所有标签,然后收集所有与指定类相同的元素。
是。但是,有几种方法可以改善您链接的页面的功能:
传入的RegExp-escape类名称,以便它不会被类名中的标点符号破坏。例如,对getElementsByClassName('ab.cd')
的调用不应与class="abxcd"
匹配。
定义getElementsByClassName
的HTML5规范允许多个以空格分隔的类名,所有这些都必须存在于要匹配的元素上。实现这一点。
可选地,允许传入标记名称的提示,以缩小函数必须查看的元素数量,以用于仅影响一种类型标记的常见情况。 (这对于真正的浏览器本地getElementsByClassName
调用无效,因此您不应依赖它来过滤掉您不想要的元素。)
示例实施:
if (!('getElementsByClassName' in document)) {
document.getElementsByClassName= function(classnames, taghint) {
var exps= classnames.split(/\s+/).map(function(name) {
name= name.replace(/([/\\^$*+?.()|[\]{}])/g, '\\$1');
return new RegExp('(^|\\s)'+name+'(\\s|$)');
});
var els= this.getElementsByTagName(taghint || '*');
var matches= [];
for (var i= 0, n= this.length; i<n; i++)
var el= els[i];
if (exps.every(function(exp) {
return exp.test(el.className);
}))
matches.push(el);
}
return matches;
};
}
然而,这也使用了IE还没有的几个ECMAScript第五版(或JavaScript 1.6)数组方法,所以你也必须为这些方法添加回退实现:
if (!('map' in Array.prototype)) {
Array.prototype.map= function(mapper, that) {
var other= new Array(this.length);
for (var i= 0, n= this.length; i<n; i++)
if (i in this)
other[i]= mapper.call(that, this[i], i, this);
return other;
};
}
if (!('every' in Array.prototype)) {
Array.prototype.every= function(tester, that) {
for (var i= 0, n= this.length; i<n; i++)
if (i in this && !tester.call(that, this[i], i, this))
return false;
return true;
};
}
答案 1 :(得分:5)
不幸的是,浏览器之间不一致。如果您不需要所有jQuery,但仍希望基于CSS选择器进行选择,请查看Sizzle,jQuery使用的选择器库。
答案 2 :(得分:3)
getElementsByClassName
混合XPath和DOM实现;尽可能使用XPath。
if (!('getElementsByClassName' in document)) {
document.getElementsByClassName = function(className, parentElement) {
if (Prototype.BrowserFeatures.XPath) {
var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
return document._getElementsByXPath(q, parentElement);
} else {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
var elements = [],
child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (Element.hasClassName(child, className)) elements.push(Element.extend(child));
}
return elements;
}
};
}
<小时/> P.S:在这里发帖因为我猜它比bobince answer快。没有冒犯:)
答案 3 :(得分:2)
某些浏览器,例如Firefox 3支持getElementsByClassName,其他浏览器必须遍历所有标记,因此如果您想支持所有具有单一功能的浏览器,则应使用迭代方法。
最好的解决方案是使用jQuery或任何其他使用最佳可用方法的框架。
答案 4 :(得分:2)
是的,您必须迭代以支持所有浏览器。如果您这样做,请确保您利用浏览器内置的功能:
if(document.getElementsByClassName) {
return document.getElementsByClassName(className);
} else {
// iterate
}
除此之外,我和Jochen在一起;使用框架