如何在单个元素上重复使用addClass和removeClass?

时间:2016-03-09 09:48:07

标签: javascript jquery

所以我想要实现的只是在每次点击时更改HTML链接的类,如下所示:

  • 删除 .first 类(如果存在),然后添加 .second
  • 删除 .second 类(如果存在),然后添加 .third
  • 删除 .third 类(如果存在),然后添加 .fourth
  • 等等......

到目前为止没有运气。我能做错什么?

这是我在尝试使用jQuery代码的单行HTML代码:

<a class="first" href="#">Test 1</a>

这是我的jQuery:

$( "#menu li a.first" ).click(function() {

   $( "#menu li a.first" ).removeClass("first").addClass("second");

}

$( "#menu li a.second" ).click(function() {

   $( "#menu li a.second" ).removeClass("second").addClass("third");

}

$( "#menu li a.third" ).click(function() {

   $( "#menu li a.second" ).removeClass("third").addClass("fourth");

}

提前致谢!

10 个答案:

答案 0 :(得分:20)

问题是您是否尝试在事件处理程序包含secondthird之前附加事件处理程序。

此外,这种方法非常冗长。我建议只提供一个类数组。像这样:

var classNames = ['first', 'second', 'third'];

然后为按钮添加不同的标识符,例如添加类class-changer。并附加以下事件处理程序。

$('.class-changer').on('click', function() {
    var $el = $(this)
    for (var i= 0; i < classNames.length; i++) {
        if ($el.hasClass(classNames[i]) && classNames[i+1]) {
           $el.removeClass(classNames[i]).addClass(classNames[i+1]);
           break;
        }
    }
});

答案 1 :(得分:10)

将所有类放在一个数组中,然后单击链接添加类,如下所示。

var classes = ["first", "second", "third", "fourth"];
$("#menu li a").click(function () {
    var index = classes.indexOf(this.className);
    var newIndex = (index + 1) % classes.length; //return to first after reaching last

    $(this).removeClass(classes[index]).addClass(classes[newIndex]);
});
.first { color: red; }
.second { color: green; }
.third { color: blue; }
.fourth { color: purple; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="menu">
    <li>
        <a class="first" href="#">Test 1</a>
    </li>
</ul>

答案 2 :(得分:4)

您可以使用.data()

来执行此操作

HTML:

<a class="first" href="#" id="test">Test 1</a>

JS:

$(".first").data("classes",["one","two","three","four"]).click(function() {
  var elem = $(this);
  var cnt = (elem.data("cnt") || 0)
  var classes = elem.data("classes");
  elem.removeClass().addClass(classes[cnt % classes.length] + " first").data("cnt",++cnt);
});

演示

$(".first").data("classes",["one","two","three","four"]).click(function() {
  var elem = $(this);
  var cnt = (elem.data("cnt") || 0)
  var classes = elem.data("classes");
  elem.removeClass().addClass(classes[cnt % classes.length] + " first").data("cnt",++cnt);
});
.one{
  color:red;
}
.two{
  color:yellow;
}
.three{
  color:green;
}
.four{
  color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<a class="first" href="#" id="test">Test 1</a>

答案 3 :(得分:4)

假设您实际上只有一个链接的状态是您尝试更改的,而不是菜单中的一堆链接,您希望所有链接都被移动到&#34; .first&#34; to&#34; .second&#34;当一个人被点击时,我会建议this作为最惯用的方式(双关语无意)。

// Only select the menu once
var $menu = $('#menu');

// Delegate to elements with the correct class.
// Specifying the "li a" is probably unnecessary,
// unless you have other elements with the same classes in "#menu".
$menu.on('click', '.first', function(e) {

    // Inside a jQuery event handler,
    // `this` refers to the element that triggered the event.
    // If the event is delegated, it's the delegation target
    // (".first" in this instance), not the bound element ("#menu").
    $(this).removeClass('first').addClass('second');

});

$menu.on('click', '.second', function(e) {
   $(this).removeClass('second').addClass('third');
});

$menu.on('click', '.third', function(e) {
   $(this).removeClass('third').addClass('fourth');
});

资源:

答案 4 :(得分:3)

不确定这是否可以解决您的问题,但我会针对条件语句进行搜索,只有一个委派事件监听器:

$("#menu li").on('click', 'a', function()
{
   if($(this).hasClass('first'))
   {
       $(this).removeClass('first').adddClass('second');
   }
   elseif($(this).hasClass('second'))
   {
       $(this).removeClass('second').adddClass('third');
   }
   // etc...
}

答案 5 :(得分:1)

如果要绑定事件,则必须先存在所选元素。

要将事件处理程序绑定到尚不存在的元素(例如动态创建或修改),您可以执行以下操作:

$(document).on('click', '#menu li a.first', function() {

    $( "#menu li a.first" ).removeClass("first").addClass("second");

});

$(document).on('click', '#menu li a.second', function() {

   $( "#menu li a.second" ).removeClass("second").addClass("third");

});

$(document).on('click', '#menu li a.third', function() {

   $( "#menu li a.third" ).removeClass("third").addClass("fourth");

});

答案 6 :(得分:0)

<a class="changable first" href="#">Test 1</a>
$( ".changable" ).click(function(event) {
classes = ['first','second','third','fourth']
changed=false
for (c in classes){
    if (event.target.classList.contains(classes[c]) && changed==false){
       $(this).removeClass((classes[c]));
       index_to_add=classes.indexOf(classes[c])+1
       class_to_add=classes[index_to_add]
       $(this).addClass(class_to_add);
       changed=true;
    }
}

});

答案 7 :(得分:0)

好的,有一些解决方法,但尚未提及。

您可以将Javascript对象用于此而不仅仅是数组。如果你想要一个链而不是列表,对象可以更容易。

var classNames = {first:'second', second:'third', third:'fourth'};

$('#menu li a').on('click', function() {
    if(typeof classNames[this.className] !== 'undefined'){
        this.className = classNames[this.className];
    }
});

第二种方法是使用.on('click', [selector], handler)代替click,它可以处理动态加载,添加或更改的元素。

$('#menu li').on('click', 'a.first', function() {
    $(this).removeClass("first").addClass("second");
});

$('#menu li').on('click', 'a.second', function() {
   $(this).removeClass("second").addClass("third");
});

$('#menu li').on('click', 'a.third', function() {
   $(this).removeClass("third").addClass("fourth");
});

甚至没有接近完美,但仍然是一个有效的解决方案。

您可以在函数内使用if .. elseswitch .. case来创建决策树。

所以基本上有很多解决方案。选择最好的。

答案 8 :(得分:0)

尝试将事件绑定到父级,

我的尝试,

var $classes = ['first', 'second', 'third'];

$(function(){
    $('#subject').click(function(){
        current = $(this).find('a:first');
        index = $.inArray(current.attr('class'), $classes);
        if($classes.length > index+1)
            current.removeClass($classes[index]).addClass($classes[index+1])
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='subject'>
	<a class="first" href="#">Test 1</a>
</div>

答案 9 :(得分:-1)

不,你不能。由于JavaScript仅在页面加载后运行(如果将它们放在$( document ).ready()函数中),则下面的其他函数将永远不会执行。它只能检测<a class="first" href="#">Test 1</a>而不能检测<a class="second" href="#">Test 1</a>,因为<a class="second" href="#">Test 1</a>是在页面加载后生成的,因此永远不会执行,除非您使用的是Ajax。

更新:可以这样做。请参阅下面的@ i3b13评论。