danielnagy
danielnagy

Reputation: 58

jQuery loop - setTimeout, addClass, removeClass

I will be an easy one for JavaScripters. I had a long research but I couldn't find the right answer. I want a menu (basically just anchors and not list elements) to be highlighted like a slider with specific time delay.

Also, it would be nice if you know how to get rid all of these useless ids around using $("#menu a") and $(this). Since I cannot do much JavaScript (although I prefer the simplicity), here is my crappy code in jQuery that works, but it's not looping.

$("#anchor1").addClass("highlight");

function loopMenu() {
    window.clearTimeout();
    setTimeout(function(){$("#anchor1").removeClass("highlight");}, 4000);
    setTimeout(function(){$("#anchor2").addClass("highlight");}, 4000);
    setTimeout(function(){$("#anchor2").removeClass("highlight");}, 8000);
    setTimeout(function(){$("#anchor3").addClass("highlight");}, 8000);
    setTimeout(function(){$("#anchor3").removeClass("highlight");}, 12000);
    setTimeout(function(){$("#anchor4").addClass("highlight");}, 12000);
    setTimeout(function(){$("#anchor4").removeClass("highlight");}, 16000);
    setTimeout(function(){$("#anchor1").addClass("highlight");}, 12000);
}

loopMenu();

What I want: a script that removes Class from current element and addClass to the next anchor type element every 4 seconds and then jump to the first element and repeat it forever.

Here is a solved question that has a few relations to this, although I can't make it work either.

Upvotes: 2

Views: 8921

Answers (5)

jhorton
jhorton

Reputation: 1059

In your anchor tags set the attribute class equal to something like "menuItem". Then in your jQuery do...

function startHighLighting(item, startTime, endTime) {    

    setInterval(function() {  
        item.addClass('highlight');  
        setInterval(function() {  
            item.removeClass('highlight');  
        }, endTime);  
    }, startTime);  
}

$("a.menuItem").each(function(index) {  
    var item = $(this),  
    baseTime = 4000,  
    highlightTime = baseTime * index,  
    unhighlightTime = baseTime * (index + 1);  

    startHighLighting(item, highlightTime, unhighlightTime);  
});

I appologize about the spacing. I'm still trying to figure out the code entry portion of this.

Upvotes: 0

Niccolò Campolungo
Niccolò Campolungo

Reputation: 12042

Use delay with jQuery objects instead of setTimeout, it is a clearer code.

$("#anchor1").addClass("highlight");
function loopMenu(){
    $("#anchor1").delay(4000).removeClass("highlight");
    $("#anchor2").delay(4000).addClass("highlight");
    $("#anchor2").delay(8000).removeClass("highlight"));
    $("#anchor3").delay(8000).addClass("highlight"));
    $("#anchor3").delay(12000).removeClass("highlight");
    $("#anchor4").delay(12000).addClass("highlight");
    $("#anchor4").delay(16000).removeClass("highlight");
    $("#anchor1").delay(16000).addClass("highlight");
    setTimeout(loopMenu, 20000);
}
loopMenu();

Upvotes: 0

Yoshi
Yoshi

Reputation: 54649

something like:

$(function () {
  var $anchors = $('.anchor');

  (function _loop(idx) {
    $anchors.removeClass('highlight').eq(idx).addClass('highlight');
    setTimeout(function () {
      _loop((idx + 1) % $anchors.length);
    }, 4000);
  }(0));
});

with:

<a class="anchor">A</a>
<a class="anchor">B</a>
<a class="anchor">C</a>
<a class="anchor">D</a>
<a class="anchor">E</a>
<a class="anchor">F</a>
<a class="anchor">G</a>

http://jsbin.com/oselux/1/

Upvotes: 6

moonwave99
moonwave99

Reputation: 22817

I would just go this way:

JS

var $anchors = $('a.anchor'), counter = 0;

setInterval(function(){

  $anchors.removeClass('highlight');
  $anchors.eq(counter++ % $anchors.length).addClass('highlight');

}, 4000);

Markup

<ul>
  <li><a href="#" class="anchor">I am an anchor</a></li>
  <li><a href="#" class="anchor">I am an anchor</a></li>
  <li><a href="#" class="anchor">I am an anchor</a></li>
  <li><a href="#" class="anchor">I am an anchor</a></li>
  <li><a href="#" class="anchor">I am an anchor</a></li>
</ul>

Fiddle.

Upvotes: 3

Kevin B
Kevin B

Reputation: 95022

simply execute loopMenu after 20 seconds to continue.

$("#anchor1").addClass("highlight");
function loopMenu(){
    //window.clearTimeout(); what was this for?
    setTimeout(function(){$("#anchor1").removeClass("highlight");}, 4000);
    setTimeout(function(){$("#anchor2").addClass("highlight");}, 4000);
    setTimeout(function(){$("#anchor2").removeClass("highlight");}, 8000);
    setTimeout(function(){$("#anchor3").addClass("highlight");}, 8000);
    setTimeout(function(){$("#anchor3").removeClass("highlight");}, 12000);
    setTimeout(function(){$("#anchor4").addClass("highlight");}, 12000);
    setTimeout(function(){$("#anchor4").removeClass("highlight");}, 16000);
    setTimeout(function(){$("#anchor1").addClass("highlight");}, 16000); // this was 12000, changed to 16000 probably a copy paste error
    setTimeout(loopMenu, 20000);
}
loopMenu();

Upvotes: 1

Related Questions