srijib mandal
srijib mandal

Reputation: 35

jQuery function call not working

I am trying to add and remove a class within a <span>, but the removeClass is not working though the function is being called.

setInterval(changeClass,4000);

var spanId=1;

function changeClass(){
 $('#'+spanId).addClass("hilite");
 setTimeout(remove, 1000);
 spanId++;}  

function remove(){
 $('#'+spanId).removeClass("hilite");
  return true;
  }

Can any one tell the reason ?

How can I do this with a while loop something like this i tried all my ways but chould not get it working

var spanSet=4;
var spanId=1;
while(spanSet > 0)
{
changeClass();
spanSet--;
}

function changeClass(){
$('#'+spanId).addClass("hilite");
setTimeout(remove, 3000);
}

function remove(){
$('#'+spanId).removeClass("hilite");
spanId++;
return true;
}

Upvotes: 1

Views: 1546

Answers (4)

Tarik
Tarik

Reputation: 81721

function changeClass(){
 $('#'+spanId).addClass("hilite");
 setTimeout(remove, 1000);
 spanId++;} 

In this code, you should execute spanId++ in a callback function which is passed as parameter to setTimeout since JS won't halt the execution until it finishes setTimeout statement.

So your code should look like this:

function changeClass(){
 $('#'+spanId).addClass("hilite");
 setTimeout(remove, 1000);
}  

function remove(){
  $('#'+spanId).removeClass("hilite");
  spanId++;
  return true;
}

Upvotes: -1

Quentin
Quentin

Reputation: 943230

spanId is being incremented before the timeout finishes, so you are trying to remove the class from the next item instead of the last item.

The usual way to avoid this problem is to use a closure, but in this case it would be much simpler to move spanId++; to the end of the remove function.

The closure approach (which I don't recommend in this case as it is overly complicated compared to just moving the increment) could look like this:

setInterval(changeClass, 4000);
var spanId = 1;

function changeClass() {
    $('#' + spanId).addClass("hilite");
    setTimeout(
        remove(spanId), // CALL remove and pass spanId as an argument
        1000
    );
    spanId++;
}

function remove(spanId) {
    return function () { // RETURN a function from remove().
        // Note: This spanId is the local variable defined in the argument list
        //       not the one that exists in the wider scope
        $('#' + spanId).removeClass("hilite");
        return true;
    }
}

Upvotes: 4

dader
dader

Reputation: 1314

You should put it that way :

setInterval(changeClass, 4000);
var spanId = 1;

function changeClass() {
    $('#'+spanId).addClass("hilite");
    setTimeout(remove, 1000);
}  

function remove() {
    $('#'+spanId).removeClass("hilite");
    spanId++;  // <--
    return true;
}

Edit : [due to Quentin suggesting to use diff tool, thank you Quentin]

I put the spanId++ at the end of remove function, so that the changeClass and remove functions are both called with the same value of spanId at each call.

Upvotes: 2

Darcey
Darcey

Reputation: 1987

This works for me, adds some timeout control too.

changeClass();

function changeClass(){
    $("#container").addClass("box");
    console.log("changeClass()");
    clearTimeout(interval);
    interval = setTimeout(remove, 1000);
}

function remove(){
    $("#container").removeClass("box");
    console.log("remove()");
    clearTimeout(interval);
    interval = setInterval(changeClass,1000);
}

Upvotes: -2

Related Questions