就像在 jQuery 中我们可以使用 $(".classname") 一样,javascript 中是否也有类似的东西?或者,如果我们没有这样的方法,那么我该如何实现。
根据http://www.dustindiaz.com/getelementsbyclass/, 我将不得不遍历所有标签,然后收集所有具有指定类的元素。
有没有更好的解决办法?
就像在 jQuery 中我们可以使用 $(".classname") 一样,javascript 中是否也有类似的东西?或者,如果我们没有这样的方法,那么我该如何实现。
根据http://www.dustindiaz.com/getelementsbyclass/, 我将不得不遍历所有标签,然后收集所有具有指定类的元素。
有没有更好的解决办法?
我将不得不遍历所有标签,然后收集所有具有指定类的元素。
是的。不过,有几种方法可以改善您链接的页面的功能:
传入的 RegExp 转义类名,这样它就不会被类名中的标点符号破坏。例如,调用不getElementsByClassName('ab.cd')
应该匹配class="abxcd"
。
定义的 HTML5 规范getElementsByClassName
允许多个以空格分隔的类名,所有这些都必须出现在元素上才能匹配。实施这一点。
可选地,允许传入标记名称的提示以缩小函数必须查看的元素数量,以查找仅影响一种类型的标记的常见情况。(这对真正的浏览器原生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 Fifth Edition(或 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;
};
}
不幸的是浏览器之间不一致。如果您不需要所有的 jQuery,但仍想根据 CSS 选择器进行选择,请查看Sizzle,jQuery 使用的选择器库。
另一个很好的实现 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;
}
};
}
一些浏览器,例如 Firefox 3 支持getElementsByClassName,其他的你必须遍历所有的标签,所以如果你想用一个函数支持所有的浏览器,你应该使用迭代方法。
最好的解决方案是使用 jQuery 或任何其他将使用最佳可用方法的框架。
是的,您必须迭代以支持所有浏览器。如果您这样做,请确保您利用浏览器存在的内置功能:
if(document.getElementsByClassName) {
return document.getElementsByClassName(className);
} else {
// iterate
}
除此之外,我和 Jochen 在一起;使用框架