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

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

答案

更改类的现代 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');

遗憾的是,尽管有一些垫片可以将其支持添加到 IE8 和 IE9 中,但这些功能在 v10 之前的 Internet Explorer 中无法使用,可从此页面获得 。但是,它越来越受到支持

简单的跨浏览器解决方案

选择元素的标准 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标志指示替换根据需要重复。

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

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

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 将功能分配给 click 事件:

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

或者,不需要 ID:

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


您也可以这样做:

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

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

document.getElementById('id').classList.toggle('class');

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

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 会更好。

您可以像这样使用node.className

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

根据PPK,这应该在 IE5.5 及更高版本中有效。

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

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

使用纯 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);
    }
}

这为我工作:

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

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

同样,您可以扩展 HTMLElement 对象,以便添加添加,删除,切换和检查类的方法( gist ):

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');
}

这是演示

只是要添加来自另一个流行框架 Google Closures 的信息,请参阅其dom / classs类:

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];

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

如果班级列表中的班级名称不止一次,您将希望在全局范围内执行此操作。而且,您可能希望从类列表的末尾删除空格,并将多个空格转换为一个空格,以免出现空格。如果仅使用类名进行拼写的代码使用下面的正则表达式并在添加名称之前将其删除,那么所有这些都应该不是问题。但。好吧,谁知道谁可能在和班级名称表打扰。

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

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, ' ') + "]");