如何在纯 JavaScript 中切换元素的类?

Posted

技术标签:

【中文标题】如何在纯 JavaScript 中切换元素的类?【英文标题】:How do I toggle an element's class in pure JavaScript? 【发布时间】:2013-09-23 17:22:27 【问题描述】:

我正在寻找一种方法来将此 jQuery 代码(用于响应式菜单部分)转换为纯 javascript

如果难以实现,可以使用其他 JavaScript 框架。

$('.btn-navbar').click(function()

    $('.container-fluid:first').toggleClass('menu-hidden');
    $('#menu').toggleClass('hidden-phone');

    if (typeof masonryGallery != 'undefined') 
        masonryGallery();
);

【问题讨论】:

***.com/questions/195951/… document.getElementById("menu").classList.toggle("hidden-phone") :-) 部分浏览器不支持classList:caniuse.com/classlist 嘿@max,想选择一个答案吗? 【参考方案1】:

2014 年回答classList.toggle() is the standard and supported by most browsers。

旧版浏览器可以使用use classlist.js for classList.toggle():

var menu = document.querySelector('.menu') // Using a class instead, see note below.
menu.classList.toggle('hidden-phone');

顺便说一句,您不应该使用 ID (they leak globals into the JS window object)。

【讨论】:

如果我们不能使用 ID,那我们该怎么做呢? 但是,我们将使用相同的类数量而不是旧的 ID,并使用类似 var myList = document.getElementsByClassName("abc") ? @goku 类不会出现在窗口对象下方。只有 ID 可以。见2ality.com/2012/08/ids-are-global.html IE10和IE11支持,第二个参数除外 非常感谢!它现在可以工作了:) 我为循环添加了更多选项: var All = document.querySelectorAll('.menu'); for (var i = 0; i 【参考方案2】:

这是使用 ES6 实现的解决方案

const toggleClass = (el, className) => el.classList.toggle(className);

使用示例

toggleClass(document.querySelector('div.active'), 'active'); // The div container will not have the 'active' class anymore

【讨论】:

ES6 很棒,但这个解决方案只是根据其他现有答案使用“document.querySelector”和“element.classList.toggle”。 “面向供应商”的解决方案无效,互联网是面向开放标准的 这不是处理大量文件的解决方案。不适用于 querySelectorAll(至少在 FF 中),因此对于那些希望在多个元素上切换类的人来说:-)(我一开始没有阅读 - 因此我的评论!)【参考方案3】:

看看这个例子:JS Fiddle

function toggleClass(element, className)
    if (!element || !className)
        return;
    

    var classString = element.className, nameIndex = classString.indexOf(className);
    if (nameIndex == -1) 
        classString += ' ' + className;
    
    else 
        classString = classString.substr(0, nameIndex) + classString.substr(nameIndex+className.length);
    
    element.className = classString;

【讨论】:

如果我在“red”之后有一个名为“redOther”的类怎么办?【参考方案4】:

这也适用于早期版本的 IE。

function toogleClass(ele, class1) 
  var classes = ele.className;
  var regex = new RegExp('\\b' + class1 + '\\b');
  var hasOne = classes.match(regex);
  class1 = class1.replace(/\s+/g, '');
  if (hasOne)
    ele.className = classes.replace(regex, '');
  else
    ele.className = classes + class1;
.red 
  background-color: red

div 
  width: 100px;
  height: 100px;
  margin-bottom: 10px;
  border: 1px solid black;
<div class="does red redAnother " onclick="toogleClass(this, 'red')"></div>

<div class="does collapse navbar-collapse " onclick="toogleClass(this, 'red')"></div>

【讨论】:

\b 单词边界与 css 类名分隔符不一致。例如,如果类名包含破折号 ("-") char: btn, btn-red will both match'\\b' + 'btn' + '\\b' !!【参考方案5】:

不需要正则表达式,只需使用类列表

var id=document.getElementById('myButton');


function toggle(el,classname)
if(el.classList.contains(classname))
el.classList.remove(classname)

else
el.classList.add(classname)






id.addEventListener('click',(e)=>

toggle(e.target,'red')
)
.red

background:red

&lt;button id="myButton"&gt;Switch&lt;/button&gt;

上面例子的简单用法

var id=document.getElementById('myButton');


function toggle(el,classname)
el.classList.toggle(classname)





id.addEventListener('click',(e)=>

toggle(e.target,'red')
)
.red

background:red

&lt;button id="myButton"&gt;Switch&lt;/button&gt;

【讨论】:

【参考方案6】:

这可能更简洁:

function toggle(element, klass) 
  var classes = element.className.match(/\S+/g) || [],
      index = classes.indexOf(klass);

  index >= 0 ? classes.splice(index, 1) : classes.push(klass);
  element.className = classes.join(' ');

【讨论】:

【参考方案7】:

如果有人希望使用 Javascript 在 mousehover/mousleave 上切换类,这里是它的代码

function changeColor() 
    this.classList.toggle('red');
    this.classList.toggle('green');


 document.querySelector('#btn').addEventListener('mouseenter', changeColor);
 document.querySelector('#btn').addEventListener('mouseleave', changeColor );

演示小提琴链接:https://jsfiddle.net/eg2k7mLj/1/

来源:Toggle Class (Javascript based, without jQuery)

【讨论】:

【参考方案8】:

试试这个(希望它会起作用):

// mixin (functionality) for toggle class 
function hasClass(ele, clsName) 
    var el = ele.className;
    el = el.split(' ');
    if(el.indexOf(clsName) > -1)
        var cIndex = el.indexOf(clsName);
        el.splice(cIndex, 1);
        ele.className = " ";
        el.forEach(function(item, index)
          ele.className += " " + item;
        )
    
    else 
        el.push(clsName);
        ele.className = " ";
        el.forEach(function(item, index)
          ele.className += " " + item;
        )
    


// get all DOM element that we need for interactivity.

var btnNavbar =  document.getElementsByClassName('btn-navbar')[0];
var containerFluid =  document.querySelector('.container-fluid:first');
var menu = document.getElementById('menu');

// on button click job
btnNavbar.addEventListener('click', function()
    hasClass(containerFluid, 'menu-hidden');
    hasClass(menu, 'hidden-phone');
)`enter code here`

【讨论】:

【参考方案9】:

这是 IE >= 9 的代码,在 className 上使用 split(" ") :

function toggleClass(element, className) 
    var arrayClass = element.className.split(" ");
    var index = arrayClass.indexOf(className);

    if (index === -1) 
        if (element.className !== "") 
            element.className += ' '
        
        element.className += className;
     else 
        arrayClass.splice(index, 1);
        element.className = "";
        for (var i = 0; i < arrayClass.length; i++) 
            element.className += arrayClass[i];
            if (i < arrayClass.length - 1) 
                element.className += " ";
            
        
    

【讨论】:

【参考方案10】:

如果你想使用原生解决方案将一个类切换为一个元素,你可以试试这个建议。我已经在不同的情况下品尝过它,无论元素上是否有其他类,我认为它非常有效:

(function(objSelector, objClass)
   document.querySelectorAll(objSelector).forEach(function(o)
      o.addEventListener('click', function(e)
        var $this = e.target,
            klass = $this.className,
            findClass = new RegExp('\\b\\s*' + objClass + '\\S*\\s?', 'g');

        if( !findClass.test( $this.className ) )
            if( klass ) 
                $this.className = klass + ' ' + objClass;
            else 
                $this.setAttribute('class', objClass);
        else 
        
            klass = klass.replace( findClass, '' );
            if(klass) $this.className = klass;
            else $this.removeAttribute('class');
        
    );
  );
)('.yourElemetnSelector', 'yourClass');

【讨论】:

【参考方案11】:

我知道我迟到了,但是,我碰巧看到这个,我有一个建议.. 对于那些寻求跨浏览器支持的人,我不推荐通过 JS 切换类。 它可能需要更多的工作,但所有浏览器都支持它。

document.getElementById("myButton").addEventListener('click', themeswitch);

function themeswitch() 
  const Body = document.body
  if (Body.style.backgroundColor === 'white') 
    Body.style.backgroundColor = 'black';
   else 
    Body.style.backgroundColor = 'white';
  
body 
  background: white;
&lt;button id="myButton"&gt;Switch&lt;/button&gt;

【讨论】:

【参考方案12】:
function navbarToggler() 
const collapseBtn = document.querySelector('.collapseBtn').classList
collapseBtn.toggle('collapse')

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案13】:

仅出于遗留原因:

function toggleClassName(elementClassName, className) 
    const originalClassNames = elementClassName.split(/\s+/);
    const newClassNames = [];
    let found = false;
    for (let index = 0; index < originalClassNames.length; index++) 
        if (originalClassNames[index] === '') 
            continue;
        
        if (originalClassNames[index] === className) 
            found = true;
            continue;
        
        newClassNames.push(originalClassNames[index]);
    
    if (!found) 
        newClassNames.push(className);
    

    return newClassNames.join(' ');


console.assert(toggleClassName('', 'foo')                        === 'foo');
console.assert(toggleClassName('foo', 'bar')                     === 'foo bar');
console.assert(toggleClassName('foo bar', 'bar')                 === 'foo');
console.assert(toggleClassName('bar foo', 'bar')                 === 'foo');
console.assert(toggleClassName('foo bar baz', 'bar')             === 'foo baz');
console.assert(toggleClassName('foo-bar', 'foo')                 === 'foo-bar foo');
console.assert(toggleClassName('bar foo-bar', 'bar')             === 'foo-bar');
console.assert(toggleClassName('bar bar bar foo-bar bar', 'bar') === 'foo-bar');
console.assert(toggleClassName(" \n\nbar-bar \nbar-baz foo", 'bar-baz') === 'bar-bar foo');

element.className = toggleClassName(element.className, 'foo');

【讨论】:

以上是关于如何在纯 JavaScript 中切换元素的类?的主要内容,如果未能解决你的问题,请参考以下文章

如何在纯Javascript中选择嵌套元素?

是啥导致无法在纯 JavaScript 中检测到滚动到 HTML 元素的底部?

有啥方法可以在纯 javascript 中将元素作为函数获取?

$(document).on() 在纯 JavaScript 中?

如何在纯javascript中显示和隐藏弹出的onclick?

JSX 在纯 JavaScript 文件中工作,如何?