题 使用JavaScript更改元素的类


如何更改HTML元素的类以响应 onClick 使用JavaScript的事件?


2290
2017-10-12 20:06


起源


“class属性主要用于指向样式表中的类。但是,它也可以由JavaScript(通过HTML DOM)用于更改具有指定类的HTML元素。” - w3schools.com/tags/att_standard_class.asp - Triynko
element.setAttribute(name, value);  更换 name 同 class。更换 value 用你给出的任何名字,用引号括起来。这避免了需要删除当前类并添加另一个类。这个 jsFiddle示例 显示完整的工作代码。 - Sandy Good
要使用onClick更改HTML元素类,请使用以下代码: <input type='button' onclick='addNewClass(this)' value='Create' />   在javascript部分: function addNewClass(elem){ elem.className="newClass"; } 线上 - Iman Bahrampour


答案:


用于更改类的现代HTML5技术

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

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中不起作用,尽管有一个 垫片 添加对IE8和IE9的支持,可从 这一页。但是,它越来越多了 支持的

简单的跨浏览器解决方案

选择元素的标准JavaScript方法是使用 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 end of string or a space)

g 如果已多次添加类名,则flag会根据需要告知replace重复。

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

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

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


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

虽然可以直接在HTML事件属性中编写JavaScript(例如 onclick="this.className+=' MyClass'")这是不推荐的行为。特别是在较大的应用程序上,通过将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为click事件分配函数:

$('#MyElement').click(changeClass);

或者,不需要id:

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



3302
2017-10-12 20:45



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


你也可以这样做:

的document.getElementById( 'ID')classList.add( '类')。
的document.getElementById( 'ID')classList.remove( '类')。

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

。的document.getElementById( '编号')classList.toggle( '类');

380
2017-08-05 17:44



我相信这是HTML5依赖。 - John
你需要Eli Gray的 classList 垫片。 - ELLIOTTCABLE
值得注意的是,这不适用于低于8的IE版本。 - Lloyd
Mozilla开发者网络 声称它在本地小于10的Internet Explorers中不起作用。在我的测试中,我发现该陈述是正确的。显然, 伊莱格雷垫片 是Internet Explorer 8-9所必需的。不幸的是,我在他的网站上找不到它(即使是搜索)。 Mozilla链接上提供了垫片。 - doubleJ
atow“classList”在IE10 +中有部分支持;不支持Opera Mini;其他标准浏览器完全支持: caniuse.com/#search=classlist - Nick Humphrey


在我没有使用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。


98
2018-05-28 07:32



当您的客户端不允许您使用jQuery时,这非常有用。 (因为你最终几乎建立了自己的图书馆。) - Mike
@Mike如果客户端不允许你使用jQuery,你能不能只通过并重建你需要的功能进入你自己的库? - kfrncs
@kfrncs因为我一般不需要那么庞大的框架。对于我想到的项目,我需要的唯一函数是3个classname(has,add,remove)函数和cookie(has,add,remove)函数。其他所有内容都是自定义的,或本机支持的。所以在缩小之前,所有东西一共只有150行,包括评论。 - Mike
老兄,凌晨4点,非常感谢你。 Vanilla JS是我们在项目中使用的,这是一个节省生命的人。 - LessQuesar
这是我最喜欢的解决方案。我到处都用它。我相信当你的项目还没有其他方法可以实现添加和删除类时,这是最优雅的方法。 - WebWanderer


您可以使用 node.className 像这样:

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

这应该适用于IE5.5及以上版本 PPK


64
2017-10-12 20:33



这将覆盖对象上的任何和所有其他类...所以它并不那么简单。 - Eric Sebasta


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

<div class="firstClass" onclick="this.className='secondClass'">

46
2018-01-05 19:14



是的,但不引人注目的JavaScript是更好的做法.. - Lloyd
我会说不引人注目的javascript是编写示例代码的可怕做法...... - Gabe
我不同意,因为我认为示例代码应该树立一个很好的例子。 - thomasrutter
一个很好的例子应该同时指导和激发想象力。它不应该取代思想,而应该激发它。 - Anthony Rutledge
其他答案并不过分,它们也会保留元素上的现有类。 - gcampbell


使用纯JavaScript代码:

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

function addClass(ele, cls) {
    if (!this.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, ' ');
    }
}

function replaceClass(ele, oldClass, newClass){
    if(hasClass(ele, oldClass)){
        removeClass(ele, oldClass);
        addClass(ele, newClass);
    }
    return;
}

function toggleClass(ele, cls1, cls2){
    if(hasClass(ele, cls1)){
        replaceClass(ele, cls1, cls2);
    }else if(hasClass(ele, cls2)){
        replaceClass(ele, cls2, cls1);
    }else{
        addClass(ele, cls1);
    }
}

40
2017-09-20 15:26



和这里一样: snipplr.com/view/3561/addclass-removeclass-hasclass - Jaider


这对我有用:

function setCSS(eleID) {
    var currTabElem = document.getElementById(eleID);

    currTabElem.setAttribute("class", "some_class_name");
    currTabElem.setAttribute("className", "some_class_name");
}

27
2017-12-08 09:36



很好的答案!刚刚添加:为selector的每个CSS类名设置,以指定一组类元素的样式 - Roman Polen.
这适用于FF,但是当我尝试使用el.className =“newStyle”时;它没用,为什么? - Lukasz 'Severiaan' Grela
您可以使用 el.setAttribute('class', newClass) 或更好 el.className = newClass。但不是 el.setAttribute('className', newClass)。 - Oriol


你也可以扩展HTMLElement对象,以便添加添加,删除,切换和检查类的方法(要旨):

HTMLElement = typeof(HTMLElement) != 'undefiend' ? HTMLElement : Element;

HTMLElement.prototype.addClass = function(string) {
  if (!(string instanceof Array)) {
    string = string.split(' ');
  }
  for(var i = 0, len = string.length; i < len; ++i) {
    if (string[i] && !new RegExp('(\\s+|^)' + string[i] + '(\\s+|$)').test(this.className)) {
      this.className = this.className.trim() + ' ' + string[i];
    }
  }
}

HTMLElement.prototype.removeClass = function(string) {
  if (!(string instanceof Array)) {
    string = string.split(' ');
  }
  for(var i = 0, len = string.length; i < len; ++i) {
    this.className = this.className.replace(new RegExp('(\\s+|^)' + string[i] + '(\\s+|$)'), ' ').trim();
  }
}

HTMLElement.prototype.toggleClass = function(string) {
  if (string) {
    if (new RegExp('(\\s+|^)' + string + '(\\s+|$)').test(this.className)) {
      this.className = this.className.replace(new RegExp('(\\s+|^)' + string + '(\\s+|$)'), ' ').trim();
    } else {
      this.className = this.className.trim() + ' ' + string;
    }
  }
}

HTMLElement.prototype.hasClass = function(string) {
  return string && new RegExp('(\\s+|^)' + string + '(\\s+|$)').test(this.className);
}

然后就这样使用(点击将添加或删除类):

document.getElementById('yourElementId').onclick = function() {
  this.toggleClass('active');
}

这是 演示


16
2018-04-11 10:13



这个有点冗长......这是一个非常简洁的解决方案......jsfiddle.net/jdniki/UaT3P - zero_cool
对不起@Jackson_Sandland,但你完全错过了这一点,完全不使用jQuery。 - moka


只是为了添加来自其他流行框架的信息,Google Closures,请参阅他们的 DOM /班 类:

goog.dom.classes.add(element, var_args)

goog.dom.classes.addRemove(element, classesToRemove, classesToAdd)

goog.dom.classes.remove(element, var_args)

选择元素的一个选项是使用 goog.dom.query 使用CSS3选择器:

var myElement = goog.dom.query("#MyElement")[0];

15
2017-11-26 21:04





以前的正则表达式上的一些小注释和调整:

如果类列表具有多次类名,您将希望全局执行此操作。而且,您可能希望从类列表的末尾删除空格并将多个空格转换为一个空格以防止空格的运行。如果使用类名称的唯一代码使用下面的正则表达式并在添加之前删除名称,则这些都不应该成为问题。但。好吧,谁知道谁可能会在班级名单上加油。

此正则表达式不区分大小写,因此在不关心类名称中的大小写的浏览器上使用代码之前,类名中的错误可能会显示出来。

var s = "testing   one   four  one  two";
var cls = "one";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "test";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "testing";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "tWo";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");

13
2018-05-02 04:59





使用JavaScript更改元素的CSS类 ASP.NET

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not Page.IsPostBack Then
        lbSave.Attributes.Add("onmouseover", "this.className = 'LinkButtonStyle1'")
        lbSave.Attributes.Add("onmouseout", "this.className = 'LinkButtonStyle'")
        lbCancel.Attributes.Add("onmouseover", "this.className = 'LinkButtonStyle1'")
        lbCancel.Attributes.Add("onmouseout", "this.className = 'LinkButtonStyle'")
    End If
End Sub

12
2018-05-28 07:19



我知道我讨厌使用ASP.NET是有原因的。 - iandisme