1

I'm trying to check list items one by one and have a 1 second delay between them. There are four lists and I can 'check the items all at the same time on load by using:

$( document ).ready( function(){
  $('#featured').children('li').each(function() { 
    $(this.tagName + '> ul').children('li').each(function() {
        $(this.tagName  + '> i').attr('class', 'fa fa-check-square-o fa-lg');       
    });
  });
});

However, when I try to include setTimeout nothing happens.

$( document ).ready( function(){
  $('#featured').children('li').each(function() { 
    $(this.tagName + '> ul').children('li').each(function() {
      setTimeout(function() 
      {
        $(this.tagName  + '> i').attr('class', 'fa fa-check-square-o fa-lg');
      }, 1000); 

    });
  });
}); 

I suspect the this variable is not within the scope of the setTimeout handler.

UPDATE:

Since I posted the question I cleaned up my code a bit. By changing this to el I was able to make the code work, however the the setTimeout function delays only once and changes the classes for all list items at the same time.

Here is my HTML (There are more items on the top list, but I reduced it to one example):

<ul id="featured">
  <li><h3>Full Home Inspections</h3>
      <ul class="fa-ul">
        <li><i class="fa fa-square-o fa-lg"></i> Gutters &amp; Downspouts</li>
        <li><i class="fa fa-square-o fa-lg"></i> Eaves, Soffits &amp; Fascia</li>
        <li><i class="fa fa-square-o fa-lg"></i> Main Water Shut-off</li>
        <li><i class="fa fa-square-o fa-lg"></i> Heating and AC</li>
      </ul>
      <a href='inspections.html'> And more</a>
  </li>
</ul>

And here is my new Script:

$( document ).ready( function(){
    $('#featured > li > ul').children('li').each(function(i, el) {
      setTimeout(function(){
        $(el.tagName + '> i').attr('class', 'fa fa-check-square-o fa-lg');
      }, (i * 1000));       
    });
});

I realize this is no longer a matter of scope, but I still need help with it, so I updated the question.

3 Answers 3

1

You're right it's not, and if you encounter this problem the fix is often to store the this variable in another local variable which remains in scope even in the nested function. However, perhaps you're looking for something like this (JSFiddle):

$(document).ready(function () {

    $('#featured').children('li').each(function () {
        lagAddingClasses($("i", this));
    });

    function lagAddingClasses($to) {
        var interval = setInterval(function() {
            if($to.length == 0) {
                clearInterval(interval);
                return;
            }
            $to.eq(0).attr('class', 'fa fa-check-square-o fa-lg');
            $to = $to.slice(1);
        }, 1000);   
    }
});

Having not seen your markup it's unclear actually what you're trying to achieve, but your selector usage seems perculiar.

Sign up to request clarification or add additional context in comments.

Comments

0

Why not:

$( document ).ready( function(){
  setTimeout(function() 
  {
    $('#featured').children('li').each(function() { 
      $(this.tagName + '> ul').children('li').each(function() {
        $(this.tagName  + '> i').attr('class', 'fa fa-check-square-o fa-lg');
      });
    });
  }, 1000);
}); 

Comments

0

Yep, its a problem about loosing scope: What you can do is save a reference of the this value in a variable and then use it inside the setTimeout.

$( document ).ready( function(){
  $('#featured').children('li').each(function() { 
    $(this.tagName + '> ul').children('li').each(function() {
      var that = this
      setTimeout(function() 
      {
        $(that.tagName  + '> i').attr('class', 'fa fa-check-square-o fa-lg');
      }, 1000); 

    });
  });
}); 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.