是否可以获取具有一个指定类的元素?这不与获取指定类的 all 的元素相同。
例如,我想捕获其类列表包含one
,two
或three
的所有元素。
也许是这样的:
var oneTwoThree = document.getElementsByClassName("one, two, three");
我也不想使用jQuery。是getElementsByClassName
每个类的唯一选项并将它们组合起来吗?
答案 0 :(得分:12)
querySelector
几乎接受任何CSS选择器:
var oneTwoThree = document.querySelectorAll('.one, .two, .three');
答案 1 :(得分:4)
我也不想使用jQuery。是每个类的getElementsByClassName的唯一选项并将它们组合起来吗?
通过使用querySelectorAll
(已回答),它将搜索并为您进行组合。
IE9 + {IE8(仅限CSS2选择器)
否则,getElementsByClassName
不是唯一可用的方法,甚至在某些旧版浏览器(IE9 +,FF3 +)上也无法使用。
但是,您可以使用的任何其他方法都需要您将结果组合在一起。所以,就像演示一样,我为你创建了几个例子。
定义HTML4.01 class attribute“此属性为一个元素分配一个类名或一组类名。可以为任意数量的元素分配相同的类名。多个类名必须用空格字符分隔。”
var whiteSpaces = '[\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]';
定义HTML5 3.2.5.7 The class attribute
每个HTML元素都可以指定一个类属性。
如果指定了属性,则该属性的值必须是一组以空格分隔的标记,表示该元素所属的各种类。
HTML元素分配给它的类包含在类空间上拆分class属性的值时返回的所有类。 (忽略重复。)
为元素分配类会影响CSS中选择器中的类匹配,DOM中的getElementsByClassName()方法以及其他此类功能。
作者可以在class属性中使用令牌没有其他限制,但鼓励作者使用描述内容性质的值,而不是描述内容所需表示的值。
DOM规范中定义的className和classList IDL属性反映了类内容属性。 [DOM]“
var whiteSpaces = '[ \n\r\t\f]';
定义开始结束echaratcers
var starts = '(^|' + whiteSpaces + ')',
ends = '(' + whiteSpaces +'|$)';
跨浏览器(DOM walker)
function walkTheDOM(node, func) {
func(node);
node = node.firstChild;
while (node) {
walkTheDOM(node, func);
node = node.nextSibling;
}
}
function getElementsByClassName1(node, className) {
var regex = new RegExp(starts + className + ends),
results = [];
walkTheDOM(node, function (currentNode) {
if (regex.test(currentNode.className)) {
results.push(currentNode);
}
});
return results;
}
跨浏览器(getElementsByClassName)
function getElementsByClassName2(node, className) {
var array = [],
regex = new RegExp(starts + className + ends),
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;
}
现代浏览器(IE9 +)
function getElementsByClassName3(node, className) {
var results = [],
treeWalker = document.createTreeWalker(
node,
NodeFilter.SHOW_ELEMENT, {
acceptNode: function (thisNode) {
var accept = NodeFilter.FILTER_SKIP;
if (thisNode.classList.contains(className)) {
accept = NodeFilter.FILTER_ACCEPT;
}
return accept;
}
}, false);
while (treeWalker.nextNode()) {
results.push(treeWalker.currentNode);
}
return results;
}
现代浏览器(IE9 +)
function getElementsByClassName4(node, className) {
return Array.prototype.slice.call(document.getElementsByClassName(className));
}
跨浏览器Array.indexOf
function indexOf(array, searchElement, fromIndex) {
var length = array.length,
val = -1,
index;
if (length !== 0) {
if (arguments.length > 2) {
fromIndex = fromIndex >> 0;
} else {
fromIndex = 0;
}
if (fromIndex < length) {
if (fromIndex < 0) {
fromIndex = length - Math.abs(fromIndex);
}
if (fromIndex < 0) {
fromIndex = 0;
}
for (index = fromIndex; index < length; index += 1) {
if (index in array && searchElement === array[index]) {
val = index;
break;
}
}
}
}
return val;
}
跨浏览器Array.filter
function filter(array, fn, thisArg) {
var length = array.length,
arr = [],
index,
element;
for (index = 0; index < length; index += 1) {
if (index in array) {
element = array[index];
if (fn.call(thisArg, element, index, array)) {
arr.push(element);
}
}
}
return arr;
};
合并结果并维持秩序
function getElements(node, classes, func) {
if (typeof classes === 'string') {
classes = classes.split(/\s*,\s*/);
}
var length = classes.length,
results = [],
index,
name;
for (index = 0; index < length; index += 1) {
name = classes[index];
if (name.charAt(0) === '.') {
name = name.slice(1);
}
results = results.concat(func(node, name));
}
return filter(results.reverse(), function (element, index, arr) {
return index <= indexOf(arr, element);
}).reverse();
}
<强>测试强>
<div class='A'></div>
<div class='B'></div>
<div class='A B'></div>
<div class='C'></div>
console.log(getElements(document, '.A, .B', getElementsByClassName1));
console.log(getElements(document, '.A, .B', getElementsByClassName2));
console.log(getElements(document, '.A, .B', getElementsByClassName3));
console.log(getElements(document, '.A, .B', getElementsByClassName4));
console.log(document.querySelectorAll('.A, .B'));
上
最后在jsPerf
上进行性能比较