Reputation: 2433
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 & Downspouts</li>
<li><i class="fa fa-square-o fa-lg"></i> Eaves, Soffits & 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.
Upvotes: 1
Views: 289
Reputation: 9347
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.
Upvotes: 1
Reputation: 573
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);
});
});
});
Upvotes: 0
Reputation: 965
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);
});
Upvotes: 0