HTML5 的隐藏宝藏:classList

如果您是 Web 开发人员,您一定知道动态更改元素的 class 属性有多么方便。这种技术的好处有很多。

  • 您可以将外观和感觉的任何更改都留给 CSS 处理。
  • 您可以避免循环遍历大量元素,因为您可以让 CSS 通过为父元素分配一个 class 来完成这项工作。
  • 您可以触发 CSS 过渡并避免编写自己的动画。
  • 以及更多……

class 的问题在于,由于它在 DOM 中的表示方式,使用起来并不简单。当您读取 className 时,您会得到一个字符串,并且需要将其分割并使用正则表达式来查找是否使用了某个 class,以及其他各种麻烦。这也是 Web 开发人员面试中一个非常常见的问题,要求编写一个处理 class 的函数。

好吧,您可能没有意识到,HTML 有一种非常酷的新方法来处理 class,称为 classList。这使得在元素上添加、删除、切换和检查 class 变得非常容易——在您的浏览器中原生实现。您可以在 JSFiddle 上试用它。

JSFiddle 演示.

您拥有的方法正是您真正需要的。

  • element.classList.add('foo') 将 class foo 添加到元素(如果它已经存在,则不执行任何操作)
  • element.classList.remove('foo') 从元素中删除 class foo
  • element.classList.toggle('foo') 交替地向元素添加和删除 class foo
  • element.classList.contains('foo') 返回 class 是否应用于元素。
  • element.classList.toString() 返回所有 class 作为字符串(与读取 className 相同)。

浏览器支持非常好,IE 是唯一不支持的浏览器。但是,有一个 Eli Grey 提供的 polyfill 供您使用。

关于 Chris Heilmann

HTML5 和开放 Web 的布道者。让我们来修复它!

更多 Chris Heilmann 的文章…


21 条评论

  1. Calvein

    此 API 最大的问题在于,您不能在多个 class 上使用这些方法。这太可惜了。

    2012 年 1 月 30 日 05:23

    1. Chris Heilmann

      您的意思是 add('foo', 'bar') 或 add(['foo', 'bar'])?这些的用例是什么?

      2012 年 1 月 30 日 05:33

      1. Calvein

        我更关注的是 `contains` 而不是 `add`。

        2012 年 1 月 30 日 05:36

        1. Greg

          它应该默认为 OR 还是 AND?

          2012 年 1 月 30 日 06:07

      2. MT

        同时操作多个 class 被大量使用,例如在 jQuery UI 中。

        有关 DOMTokenList 在无法同时操作多个标记方面的问题的详细信息,请参阅 https://www.w3.org/Bugs/Public/show_bug.cgi?id=13999

        2012 年 1 月 30 日 06:10

      3. mig

        经常使用 jQuery,我发现自己经常执行 $(element).addClass("foo bar") 或 $(element).removeClass("foo bar")。这是一个很好的便利功能。

        2012 年 1 月 30 日 07:12

  2. Mustafa

    太棒了 :)

    不过有一点,文章标题说的是 HTML5,但这不是 JavaScript 吗?

    2012 年 1 月 30 日 05:24

    1. Chris Heilmann

      它是活动 HTML 规范的一部分——它是一个 HTML 属性。所以它是 HTML5。规范中描述了许多 JavaScript。

      2012 年 1 月 30 日 05:34

      1. Mustafa

        谢谢您澄清这一点 :)

        2012 年 1 月 31 日 13:48

  3. Joost Elfering

    这是新的 HTML5 规范中的一颗好宝石!

    支持似乎还不错,但自然需要一个回退方案。与解决此问题的 jQuery 类型解决方案相比,是否有任何性能数据?

    2012 年 1 月 30 日 05:46

  4. Motyar

    很高兴知道,我将用它创造一些令人惊叹的东西。

    2012 年 1 月 30 日 06:25

  5. MT

    我们可能应该有单独的方法,例如

    — contains() 用于 AND(如果元素具有所有给定的标记,则返回 true);

    — containsOne() 用于 OR(如果元素具有任何给定的标记,则返回 true)。

    2012 年 1 月 30 日 07:47

  6. MT

    这是对 Greg 评论的回复
    hacks.mozilla.org/2012/01/hidden-gems-of-html5-classlist/comment-page-1/#comment-1328637

    2012 年 1 月 30 日 07:49

  7. Rob

    这很酷,但我最常在 jQuery 中使用的 class 工具是 toggleClass,第二个参数是布尔值。

    2012 年 1 月 30 日 07:53

    1. Chris Heilmann

      这对您来说很好,但 jQuery 不是标准,需要单独加载。这并不总是可行的。

      2012 年 1 月 30 日 08:42

  8. louisremi

    classList API 确实非常好,但如果您正在寻找跨浏览器解决方案,这里有一个 140 字节的函数:https://gist.github.com/1319121

    API 是
    c( elem, “has”, name );
    c( elem, “add”, name );
    c( elem, “remove”, name );
    c( elem, “toggle”, name );

    2012 年 1 月 30 日 08:22

  9. Brian Birtles

    需要注意的是,WebKit 对 classList 的支持不扩展到内联 SVG(不像 Firefox 和 Opera)。为了解决这个问题,我修改了 Eli Grey 的 shim
    https://github.com/birtles/parapara/blob/master/editor/js/svgClassList.js

    它还扩展了对通过 (但尚未或) 嵌入的 SVG 的支持。

    2012 年 1 月 30 日 16:38

  10. Brian Birtles

    显然您不能在此处的帖子中使用尖括号。上一条评论应该说修改后的 classList 尚未扩展对嵌入元素或 iframe 元素的支持。

    2012 年 1 月 30 日 16:40

  11. Drew

    如果此原生方法比 jQuery 的当前方法更快,我预计他们可能会在可用时更新代码以使用它。

    2012 年 1 月 31 日 10:35

  12. Coursework

    无论何时在我的网站上构建任何页面,我都会使用 classList。我使用 classList 在各种静态网页中构建了许多配色方案。您分享的方法中,有些我以前不知道,现在对我和其他 HTML 开发人员来说非常有用。

    2012 年 3 月 15 日 04:33

  13. sam

    我刚刚编写了一个 jsperf 来测试一个简单的“contains”测试,发现它比简单的 indexOf() 测试慢 50%。这很可惜,因为 indexOf() 通常不是搜索字符串的最快方法。

    http://jsperf.com/html5-class-list

    2012 年 10 月 18 日 14:41

此文章的评论已关闭。