JQuery - Cycle a class with timer

2019-06-03 01:18发布

I've a list wit below structure

<div id="slider">
  <ul>
    <li class='active'> a </li>
    <li> b </li>
    <li> c </li>    
    <li> d </li>
    <li> e </li>
  </ul>
</div>

I need to change the class 'active' of li's in a cycling manner Here is the script I'm working with. issue is it either adds the class active to all li's or removes the class active from all li's

      toggleSlide = function(){
          $("#slider ul li").each(function(index) {
            if($(this).hasClass('active')){

              $("#slider ul li").removeClass('active');
              $(this).next().addClass('active'));
              //lis = $("#slider ul li")
              //$(lis[(index+1)%lis.length]).addClass('active');
            }
          });
        }
   setInterval(toggleSlide, 5000);​

3条回答
太酷不给撩
2楼-- · 2019-06-03 01:23

I'd go for something far simpler

toggleSlide = function() {
    var active = $("#slider ul li.active");
    var next   = active.next();
    if (next.length === 0) {
        next = $('#slider ul li:first');
    }

    active.removeClass('active');
    next.addClass('active');
}
setInterval(toggleSlide, 1000);

http://jsfiddle.net/HyRYC/1/

Basically, find the active item and save it to a local var. Then find the item after it and save that too. Now if the last one is active, then next() will return a jQuery object with no matches, meaning it has a length of zero. In that case, find the first item to be our next.

No we simply remove the active class from the current active item, and add it to our next one.

查看更多
We Are One
3楼-- · 2019-06-03 01:26

You can greatly simplify this with .add() and .last() since elements from .add() are turned in document order, it would look like this:

var toggleSlide = function(){
  $("#slider li.active").removeClass()
   .next().add("#slider li:first").last().addClass("active");
}
setInterval(toggleSlide, 5000);

You can test it here (1000ms duration for the demo)

How this works is it takes the next <li> if there is one, then adds the first one as well, by using .last() (since they're in document order) we'll get the .next() one if it's there, otherwise the set only contains one element, the :first <li>, and we're back to the beginning.

查看更多
淡お忘
4楼-- · 2019-06-03 01:38

This should work a bit better:

toggleSlide = function() {    
    var $active = $('#slider ul li.active');
    if($active.length == 0) {
        $active = $('#slider ul li:first');
    }
    $active.removeClass('active');
    if($active.next('li').length > 0) {
        $active.next('li').addClass('active');
    } else {
        $('#slider ul li:first').addClass('active');
    }
}
setInterval(toggleSlide, 5000);​

You don't need the .each() loop and that's what was causing your issues. You only need to work on the current active element.

Live example:

http://jsfiddle.net/MS5DV/

查看更多
登录 后发表回答