使用JavaScript添加或删除类的最有效方法

7

我很好奇有没有人知道这两种方法哪个更有效率,我只关心Firefox浏览器,不需要知道在IE中这段代码不起作用等等...

基本上根据输入字段的值,我正在显示和隐藏DOM元素,即瞬间搜索。如果没有搜索结果,我需要显示或隐藏“未找到任何内容”的元素。我想知道,检查“未找到任何内容”元素是否处于适当状态再修改其类属性是否更便宜(更有效),还是直接修改该类属性。

问题:无论元素的类属性是否有变化,每次运行函数时都应该删除/添加隐藏类吗?

if (shown_count > 0) {
    element.classList.add('hidden');
}
else {
    element.classList.remove('hidden');
}

或者我应该在实际更新元素之前检查它是否需要更新其类属性?
if (shown_count > 0) {
    if (element.classList.contains('hidden') == false) {
         element.classList.add('hidden');
    }
}
else {
    if (element.classList.contains('hidden')) {
         element.classList.remove('hidden');
    }
}

5
使用jsperf或类似工具创建一个基准测试会比我们回答你的问题更好,我相信。 - Frédéric Hamidi
2
很好的问题。看起来可能取决于任何给定查询中需要更改的元素百分比。例如,如果100%需要更改,则第一种方法显然更有效。如果少于100%需要更改,则答案可能会改变。 - A F
Aakil,我不是在问如何显示/隐藏实际的搜索结果,而是在问是否应该每次在函数结束时修改一个元素的类属性,还是仅在类应该更改时修改。 - macguru2000
2个回答

7

我认为本地代码已经完成了存在性检查,所以你不需要再次检查。

现在让我们来看看源代码(注意:classListDOMTokenList对象)

String DOMTokenList::addToken(const AtomicString& input, const AtomicString& token)
{
    if (input.isEmpty())
        return token;

    StringBuilder builder;
    builder.append(input);
    if (input[input.length()-1] != ' ')   // <--- check happens here
        builder.append(' ');
    builder.append(token);
    return builder.toString();
}

来自WebKit的WebCore源代码。

2
有任何证据或文件支持这个吗?我相信你是正确的...但是想要确认一下。谢谢。 - macguru2000
1
我不确定WebKit的源代码与问题有什么关系(问题特别涉及Firefox)。即使对于WebKit,您也正在查看错误的函数。您需要使用ClassList :: addInternal。但是,是的,规范要求类列表上的add()方法在添加之前检查类是否已存在。因此,它不会重复添加。 - Boris Zbarsky
@BorisZbarsky 我只是以WebKit的源代码为例,classList在WebKit里不就是DOMTokenList吗?我在Chrome里看到的也是DOMTokenList - xdazz
实现是DOMTokenList的子类,覆盖了各种方法。但重点是你引用的代码没有进行任何形式的“令牌已在列表中”检查。这个检查发生在ClassList :: addInternal中。 - Boris Zbarsky
除了浏览器的特异性和确切的源代码之外,xdazz是正确的,我的jsperf测试显示了这一点,请查看http://jsperf.com/add-remove-class-performanci。 - macguru2000
有趣的是,现在看来相反的情况似乎是真的,在Chrome 83.0.4103.10,MacOS 10.14上,在更改类之前检查是否应该更改类至少比直接更改类要快得多。 - macguru2000

2
在jsperf上进行了一些测试后,答案很简单,第一个选项更快。这很可能是因为xdazz的回答,即classList.add方法已经进行了检查。
这是性能测试的链接:http://jsperf.com/add-remove-class-performanci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接