如何使用 JavaScript 更改元素的类?

IT技术 javascript html dom
2020-12-19 00:22:38

如何onclick使用 JavaScript更改 HTML 元素的类以响应一个或任何其他事件?

6个回答

用于更改类的现代 HTML5 技术

现代浏览器添加了classList,它提供了一些方法,可以在不需要库的情况下更轻松地操作类:

document.getElementById("MyElement").classList.add('MyClass');

document.getElementById("MyElement").classList.remove('MyClass');

if ( document.getElementById("MyElement").classList.contains('MyClass') )

document.getElementById("MyElement").classList.toggle('MyClass');

不幸的是,这些在 v10 之前的 Internet Explorer 中不起作用,尽管有一个shim可以将它的支持添加到 IE8 和 IE9,可从此页面获得不过,它得到越来越多的支持

简单的跨浏览器解决方案

选择元素的标准 JavaScript 方法是 using document.getElementById("Id"),这是以下示例使用的 - 您当然可以通过其他方式获取元素,并且在正确的情况下可以简单地使用this- 但是,对此进行详细说明超出了范围的答案。

要更改元素的所有类:

要用一个或多个新类替换所有现有类,请设置 className 属性:

document.getElementById("MyElement").className = "MyClass";

(您可以使用空格分隔的列表来应用多个类。)

向元素添加额外的类:

要将类添加到元素,而不删除/影响现有值,请附加一个空格和新类名,如下所示:

document.getElementById("MyElement").className += " MyClass";

从元素中删除类:

要将单个类删除到元素,而不影响其他潜在类,需要一个简单的正则表达式替换:

document.getElementById("MyElement").className =
   document.getElementById("MyElement").className.replace
      ( /(?:^|\s)MyClass(?!\S)/g , '' )
/* Code wrapped for readability - above is all one statement */

这个正则表达式的解释如下:

(?:^|\s) # Match the start of the string or any single whitespace character

MyClass  # The literal text for the classname to remove

(?!\S)   # Negative lookahead to verify the above is the whole classname
         # Ensures there is no non-space character following
         # (i.e. must be the end of the string or space)

g标志告诉替换根据需要重复,以防多次添加类名。

要检查类是否已应用于元素:

上面用于删除类的相同正则表达式也可以用作检查特定类是否存在:

if ( document.getElementById("MyElement").className.match(/(?:^|\s)MyClass(?!\S)/) )

### 将这些操作分配给 onclick 事件:

虽然可以直接在 HTML 事件属性(例如onclick="this.className+=' MyClass'")中编写 JavaScript,但这是不推荐的行为。特别是在较大的应用程序中,通过将 HTML 标记与 JavaScript 交互逻辑分离来实现更易于维护的代码。

实现这一点的第一步是创建一个函数,并在 onclick 属性中调用该函数,例如:

<script type="text/javascript">
    function changeClass(){
        // Code examples from above
    }
</script>
...
<button onclick="changeClass()">My Button</button>

(不需要在脚本标签中包含此代码,这只是为了示例的简洁,将 JavaScript 包含在不同的文件中可能更合适。)

第二步是将 onclick 事件从 HTML 中移到 JavaScript 中,例如使用addEventListener

<script type="text/javascript">
    function changeClass(){
        // Code examples from above
    }

    window.onload = function(){
        document.getElementById("MyElement").addEventListener( 'click', changeClass);
    }
</script>
...
<button id="MyElement">My Button</button>

(请注意,window.onload 部分是必需的,以便在 HTML 完成加载执行该函数的内容- 如果没有这个,调用 JavaScript 代码时 MyElement 可能不存在,因此该行将失败。)


JavaScript 框架和库

上面的代码全部使用标准 JavaScript,但是,通常的做法是使用框架或库来简化常见任务,并从编写代码时可能没有想到的固定错误和边缘情况中受益。

虽然有些人认为添加一个约 50 KB 的框架来简单地更改类是多余的,但如果您正在执行任何大量的 JavaScript 工作或任何可能具有不寻常的跨浏览器行为的工作,那么非常值得考虑。

(粗略地说,库是为特定任务设计的一组工具,而框架通常包含多个库并执行一套完整的职责。)

下面使用jQuery复制了上面的示例,它可能是最常用的 JavaScript 库(尽管还有其他值得研究的库)。

(注意$这里是 jQuery 对象。)

使用 jQuery 更改类:

$('#MyElement').addClass('MyClass');

$('#MyElement').removeClass('MyClass');

if ( $('#MyElement').hasClass('MyClass') )

此外,jQuery 提供了一个快捷方式来添加一个不适用的类,或者删除一个适用的类:

$('#MyElement').toggleClass('MyClass');

### 使用 jQuery 为单击事件分配一个函数:
$('#MyElement').click(changeClass);

或者,不需要 id:

$(':button:contains(My Button)').click(changeClass);

很好的答案彼得。一个问题……为什么使用 JQuery 比使用 Javascript更好JQuery 很棒,但如果这就是您需要做的全部 - 有什么理由包括整个 JQuery 库而不是几行 JavaScript?
2021-02-09 00:22:38
如果您尝试删除类“myClass”并且您有一个类“prefix-myClass”,则您在上面给出的用于删除类的正则表达式将在您的 className 中留下“prefix-”:O
2021-02-12 00:22:38
哇,三年和 183 票赞成,直到现在还没有人发现。感谢 jinglesthula,我已经更正了正则表达式,因此它不会错误地删除部分类名。// 我想这是一个很好的例子,说明了为什么框架(如 jQuery)值得使用 - 像这样的错误会被更快地捕获和修复,并且不需要更改普通代码。
2021-02-23 00:22:38
此解决方案的一个错误:当您多次单击按钮时,它将多次向元素添加“MyClass”类,而不是检查它是否已存在。因此,您最终可能会得到一个看起来像这样的 HTML 类属性:class="button MyClass MyClass MyClass"
2021-03-04 00:22:38
@mattstuehler 1)短语“更好的x”通常意味着“更好的(你可以)x”。2) 说到问题的核心,jQuery 旨在帮助访问/操作 DOM,并且如果您需要在所有地方都做这种事情时,通常会这样做。
2021-03-05 00:22:38

你也可以这样做:

document.getElementById('id').classList.add('class');
document.getElementById('id').classList.remove('class');

并切换一个类(如果存在则删除,否则添加它):

document.getElementById('id').classList.toggle('class');
我相信这是 HTML5 依赖的。
2021-02-20 00:22:38
atow "classList" 在 IE10+ 中有部分支持;不支持 Opera Mini;其他标准浏览器完全支持:caniuse.com/#search=classlist
2021-02-25 00:22:38
2021-02-27 00:22:38
Mozilla 开发人员网络声明它本身在 Internet Explorer 中不工作 10。在我的测试中,我发现该声明是正确的。显然,Internet Explorer 8-9 需要Eli Gray 垫片不幸的是,我在他的网站上找不到它(即使搜索)。该垫片可在 Mozilla 链接上找到。
2021-03-03 00:22:38
你需要 Eli Grey 的classList垫片。
2021-03-08 00:22:38

在我没有使用 jQuery 的旧项目之一中,我构建了以下函数来添加、删除和检查元素是否具有类:

function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}

function addClass(ele, cls) {
    if (!hasClass(ele, cls))
        ele.className += " " + cls;
}

function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        ele.className = ele.className.replace(reg, ' ');
    }
}

因此,例如,如果我想onclick向按钮添加一些类,我可以使用它:

<script type="text/javascript">
    function changeClass(btn, cls) {
        if(!hasClass(btn, cls)) {
            addClass(btn, cls);
        }
    }
</script>
...
<button onclick="changeClass(this, "someClass")">My Button</button>

到目前为止,使用 jQuery 肯定会更好。

@Mike 如果客户端不允许您使用 jQuery,您是否可以不只是遍历并将您需要的功能重新构建到您自己的库中?
2021-02-10 00:22:38
需要注意的是addClassremoveClass在同一个元素上使用and,元素的className会包含一个额外的空格。的 className 修改行removeClass应更新为ele.className = ele.className.replace(reg, ' ').trim().replace(/\s{2,}/g, ' ');. 这将删除剩余的尾随空格并将多个空格折叠为 className 中的单个空格。
2021-02-16 00:22:38
当您的客户端不允许您使用 jQuery 时,这非常有用。(因为你最终几乎建立了自己的图书馆。)
2021-02-17 00:22:38
这是我最喜欢的解决方案。我到处都用它。我相信当您的项目还没有其他方法时,这是实现添加和删除类的最优雅的方法。
2021-02-21 00:22:38
@kfrncs 因为我通常不需要那么大的框架。对于我正在考虑的项目,我唯一需要的函数是 3 个 classname(has,add,remove) 函数和 cookie(has, add, remove) 函数。其他一切要么是自定义的,要么是原生支持的。所以所有的东西在缩小之前只有 150 行,包括评论。
2021-03-03 00:22:38

你可以node.className像这样使用

document.getElementById('foo').className = 'bar';

根据PPK,这应该适用于Internet Explorer 5.5及更高版本

这将覆盖对象上的任何和所有其他类......所以它不是那么简单。
2021-02-23 00:22:38

哇,很惊讶这里有这么多矫枉过正的答案......

<div class="firstClass" onclick="this.className='secondClass'">
其他答案并不过分,它们还保留了元素上的现有类。
2021-02-09 00:22:38
我会说不引人注目的 javascript 是编写示例代码的可怕做法......
2021-02-10 00:22:38
一个好的例子应该同时指导和激发想象力。它不应该取代思想,而应该激发它。
2021-02-17 00:22:38
我不同意,因为我认为示例代码应该是一个很好的例子。
2021-02-20 00:22:38