具有两个类的getElementsByClassName()


Answers:


125

您不能使用getElementsByClassName()method来做到这一点,而只能使用querySelectorAll()带有逗号分隔的类选择器的method。

document.querySelectorAll('.a,.b')

2
这是正确的答案,但是请注意,对IE8的支持仅适用于CSS2选择器,而对IE <= 7则不提供支持,因此在这种情况下,您需要按类进行两个选择。
zoubida13 2013年

1
我看到了您的编辑,但是getElementsByClassName在IE <= 7中也不起作用,我只是为了完成此操作而发布了替代答案,但您的答案应被OP评为最佳答案。
zoubida13 '16

1
@ zoubida13:怎么.a,.b不只是两个CSS2选择器?
BoltClock

3
@ zoubida13:我不认为仍有人在使用IE <= 7:);)
Pranav C Balan

5
甚至Microsoft也不支持IE7。为什么公司或开发人员仍然这样做,我听不懂!
2013年

24

可以通过getElementsByClassName()使用空格分隔多个类名来传递它们:

var elems = document.getElementsByClassName("class1 class2 class3");

现在,这与.querySelectorAll(".class1,.class2,.class3")方法不同之处在于它应用了一个连词,而不是一个析取词-“和”而不是“或”。从而

var elems = document.getElementsByClassName("class1 class2 class3");

就好像

var elems = document.querySelectorAll(".class1.class2.class3");

有时您想要一个,有时您想要另一个。的确,它.querySelectorAll()为您提供了更大的灵活性。


5
这个不对。它将搜索具有所有三个类的元素
未知开发人员

7
那是“与”而不是“或”
epascarello,2016年

2
@epascarello是的,我明白了;这只是一个答案。
尖尖的2016年

2
这个答案不起作用。它只会返回具有所有指定类的元素。
安迪·默瑟

6
这是回答错误问题的答案,所提供的信息与提出的问题并不完全相关。OP已经知道的可能性更大。因此,这主要是噪音。
Spencer Wieczorek

8

不,您仅凭一个document.getElementsByClassName()电话就无法实现这一目标。该函数返回具有第一个参数中指定的所有类的元素,以空格分隔。

有两种可能的解决方案。首先是document.querySelectorAll()使用CSS选择器。

document.querySelectorAll(".a, .b")

第二种解决方案是调用document.getElementsByClassName()两次,使用将结果转换成数组,然后使用Array.from()合并它们Array.prototype.concat()。为了避免重复(例如,当元素有两个 ab类),你必须创建一个新的集合从数组,然后使用重新设置为阵列Array.from()

const classA = Array.from(document.getElementsByClassName("a"))
     ,classB = Array.from(document.getElementsByClassName("b"))
     ,result = Array.from(new Set(classA.concat(classB)))

请参见下面的演示:

console.log("first solution", document.querySelectorAll(".a, .b"))

const classA = Array.from(document.getElementsByClassName("a"))
     ,classB = Array.from(document.getElementsByClassName("b"))
     ,result = Array.from(new Set(classA.concat(classB)))

console.log("second solution", result)
<div class="a"></div>
<div class="b"></div>
<div class="a b"></div>
<div class="c"></div>

请注意,第一个解决方案给出了一个类似数组的NodeList对象,而第二个解决方案给出了一个数组。


3
使用Set毫无意义,因为不支持querySelectorAll的浏览器不支持Set。
2016年

3
@Somnium它并不像看起来那样毫无意义。Babel支持Set,但不支持document.querySelectorAll()(因为它不是ECMAScript的一部分,而是Web API的一部分)。如果使用Babel编译代码,则第二个解决方案将在所有浏览器中运行。坦白说,我写第二个解决方案不是为了好玩,而是作为一个真正的解决方案。
米哈尔Perłakowski

Array.from在Internet Explorer 11中产生问题。–
Kamlesh

6

只是为了增加一点支持,这是一个与IE的较早版本兼容并使用纯香草js的版本:

function getElementsByClassNameOr(root, classNameString) // classNameString like '.a, .b' don't forget the comma separator
 {
    var arr = [],
    rx = new RegExp('(^|[ \n\r\t\f])' + classNameString + '([ \n\r\t\f]|$)'),
    elements = root.getElementsByTagName("*");

    var elem;

    for (i=0 ; i < elements.length ; i++) {
        elem = elements[i];
        if (rx.test(elem.className)) {
            arr.push(elem);
        }

    }

    return arr; // will contain all the elements that have one of the classes in ClassNameString, root can be document or a div.
}

1
这将是非常低效的。请注意,通过支持较旧的浏览器,一种目标是much slower浏览器。在这种情况下,性能至关重要。我建议使用多次调用Element.getElementsByClassName并使用结果的串联数组。
蒂姆(Tim)

1
@Tim您对性能是正确的,尽管在这种情况下性能至关重要,这完全取决于您的解释。您的建议既无效又不详尽。getElementsByClassName方法未完全在IE <9.支持
zoubida13

1
@ zoubida13您完全正确。除了这个答案,似乎没有其他方法可以提供更好的性能。
蒂姆(Tim)

1
@Blender我用分号替换了逗号,这的确是错字。
zoubida13 '16

1
@ zoubida13:您的代码假定类名彼此相邻,因此class="a b c"当您使用进行搜索时,该类名将无效'a c'
Blender
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.