getElementsByClassName() 有两个类

IT技术 javascript html dom
2021-03-08 14:14:10

是否可以使用类a b使用getElementsByClassName()一次来获取所有元素我更喜欢香草 JavaScript。

4个回答

您不能使用getElementsByClassName()方法来实现,而是使用querySelectorAll()带有逗号分隔的类选择器的方法。

document.querySelectorAll('.a,.b')
连微软都不支持IE7了。为什么公司或开发人员仍然这样做,我无法理解!
2021-04-23 14:14:10
我看到您的编辑,但 getElementsByClassName 在 IE <= 7 中也不起作用,我发布了一个替代答案来完成此操作,但您的答案应该被 OP 投票为最佳答案。
2021-04-24 14:14:10
@zoubida13:怎么.a,.b不是只有两个 CSS2 选择器?
2021-05-01 14:14:10
@zoubida13:我认为没有人还在使用IE <= 7:) ;)
2021-05-07 14:14:10
这是正确的答案,但请注意,对 IE8 的支持仅适用于 CSS2 选择器,不支持 IE <= 7,因此在这种情况下,您需要按类进行两次选择。
2021-05-10 14:14:10

可以通过getElementsByClassName()用空格分隔传递多个类名

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

现在,这与.querySelectorAll(".class1,.class2,.class3")方法的不同之处在于它应用了连词,而不是析取——“and”而不是“or”。因此

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

就好像

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

有时你想要一个,有时你想要另一个。这绝对是正确的,它.querySelectorAll()为您提供了更多的灵活性。

这个答案不起作用。它只会返回具有所有指定类的元素。
2021-04-19 14:14:10
那是“AND”而不是“OR”
2021-05-06 14:14:10
这个不对。它将搜索具有所有三个类的元素
2021-05-11 14:14:10
这是一个回答错误问题的答案,提供的信息与提出的问题并不完全相关。而且很可能是 OP 已经知道的事情。因此,这主要是噪音。
2021-05-11 14:14:10
@epascarello 是的,我明白了;这只是一个答案。
2021-05-12 14:14:10

不,你不能只通过一个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对象,而第二个解决方案只提供了一个数组。

@Somnium 它并不像看起来那么毫无意义。Babel 支持 Set,但不支持document.querySelectorAll()(因为它不是 ECMAScript 的一部分,而是 Web API 的一部分)。如果您使用 Babel 编译您的代码,则第二种解决方案将适用于所有浏览器。坦率地说,我写第二个解决方案是为了好玩,而不是作为一个真正的解决方案。
2021-04-17 14:14:10
Array.from 在 Internet Explorer 11 中产生问题。
2021-04-27 14:14:10
使用Set是没有意义的,因为在那些不支持querySelectorAll的浏览器中是不支持的。
2021-05-16 14:14:10

只是为了添加更多支持,这里有一个与旧版本 IE 兼容并使用纯 vanilla 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.
}
@Blender 我用分号替换了逗号,确实是打字错误。
2021-04-25 14:14:10
这将是非常低效的。请注意,通过支持旧浏览器,一种是针对much slower浏览器。在这种情况下,性能至关重要,我建议多次调用Element.getElementsByClassName并使用结果的连接数组。
2021-05-02 14:14:10
@zoubida13:您的代码假定类名彼此相邻,因此class="a b c"当您使用'a c'.
2021-05-06 14:14:10
@Tim 您对性能的看法是正确的,尽管在这种情况下性能至关重要这一事实完全取决于您的解释。你的建议既不正确也不详细。IE < 9 不完全支持 getElementsByClassName。
2021-05-10 14:14:10
@zoubida13 你是完全正确的。除了这个具有更好性能的答案之外,似乎没有其他方法。
2021-05-10 14:14:10