2012-02-06 19 views
9

cssLàm thế nào để vượt qua 'này' thành một callback setTimeout

.item { 
    display: none; 
} 

html

<div> 
    <div class="item">machin</div> 
    <div class="item">chose</div> 
    <div class="item">chouette</div> 
    <div class="item">prout</div> 
</div> 

Tôi đang sử dụng jQuery và tôi muốn để làm cho mỗi .item xuất hiện sau một bộ hẹn giờ nhỏ ngẫu nhiên như:

javascript

$('.item').each(function() { 
    itm = $(this); 
    setTimeout(function() { 
    itm.fadeIn(1000); 
    }, Math.floor(Math.random() * 1000)); 
}) 

Ở đây, itm sẽ luôn chứa mục cuối cùng vì hàm được đánh giá sau tất cả các bài tập.
Tôi không thể sử dụng thông số thứ 3 của setTimeout() vì thông số này sẽ không hoạt động trên IE.
Bạn không nên sử dụng setTimeout() với phương pháp eval vì lý do bảo mật.

Vậy làm cách nào tôi có thể truy cập vào đối tượng của mình thông qua setTimeout()?


Sửa

Tôi biết rằng câu hỏi này đã được đăng.
Nhưng tôi cho rằng nó hơi cụ thể với ngữ cảnh each().
Bây giờ một người nào đó đã hoàn toàn thay đổi tiêu đề của câu hỏi của tôi mà ban đầu được một cái gì đó giống như 'setTimeout() - jQuery.each() đối tượng tham số này'

+0

'this' bên trong của 'setTimeout()' đề cập đến đối tượng toàn cầu. Mã của bạn ở trên thậm chí không nên hoạt động cho mục cuối cùng. –

+0

Xin lỗi tôi đã thực sự làm 'itm = $ (this)' trong mã của tôi thay vì 'var itm = $ (this)', tôi đã cập nhật câu hỏi của mình. Sau đó, bây giờ tôi không biết câu trả lời để chấp nhận :) –

+3

@PierredeLESPINAY Aha. Sự khác biệt giữa 'var itm' và' itm' là không có 'var', nó là một biến toàn cầu đơn lẻ, thay vì một biến cục bộ cho mỗi cuộc gọi của hàm kèm theo. Đó là lý do tại sao setTimeout chỉ từng thấy phần tử cuối cùng trong danh sách. – Izkata

Trả lời

2

Bạn cần lưu trữ this trong một biến riêng biệt:

$('.item').each(function() { 
    var me = $(this); 
    setTimeout(function() { 
    me.fadeIn(1000); 
    }, Math.floor(Math.random() * 1000)); 
}) 
2

Bí quyết ở đây là để tiết kiệm this thành một địa phương có thể được đánh giá một cách an toàn trong setTimeout callback

$('.item').each(function() { 
    var self = this; 
    setTimeout(function() { 
    $(self).fadeIn(1000); 
    }, Math.floor(Math.random() * 1000)); 
}); 
2

Hãy thử điều này:

$('.item').each(function() { 
var myVar = $(this); 
setTimeout(function() { 
myVar.fadeIn(1000); 
}, Math.floor(Math.random() * 1000)); 
}) 
2

Hãy thử insteed này:

$('.item').each(function() { 
     var elm = this; 
     setTimeout(function() { 
     $(elm).fadeIn(1000); 
     }, Math.floor(Math.random() * 1000)); 
    }) 

Tôi không thể giải thích lý do tại sao nó hoạt động, nhưng tôi nghĩ rằng đây là một tham chiếu đến một "điều này" trong setTimeout của bạn.

http://jsfiddle.net/Pdrfz/

2

Hãy thử điều này:

$('.item').each(function() { 
    var item =$(this); 
    setTimeout(function() { 
      item.fadeIn(1000); 
     }, 
     Math.floor(Math.random() * 1000)); 
    }); 
3

Trước setTimeout thực hiện each vòng lặp sẽ hoàn tất thi công, nó sẽ không chờ đợi. Cũng trong hàm setTimeoutthis sẽ không tham chiếu đến phần tử DOM.

Hãy thử một cái gì đó như thế này.

function fadeItem(item){ 
    item.fadeIn(1000); 
} 

$('.item').each(function() { 
    var $item = $(this); 
    setTimeout(function() { 
    fadeItem($item); 
    }, Math.floor(Math.random() * 1000)); 
}); 

Bạn cũng có thể thử một cái gì đó như thế này.

var $items = $('.item'), count = 0; 

function fadeItem(item){ 
    item.fadeIn(1000); 
    if(count < $items.length){ 
     setTimeout(function(){ 
      fadeItem($items.eq(count++)); 
     }, Math.floor(Math.random() * 1000)); 
    } 
} 
setTimeout(function(){ 
    fadeItem($items.eq(count++)); 
}, Math.floor(Math.random() * 1000)); 
Các vấn đề liên quan