Проблемы с setTimeout () внутри jQuery .each - PullRequest
3 голосов
/ 10 января 2012

Следующий код не будет работать должным образом.Я пробовал разные варианты и искал везде, но не повезло.

i = 1;
var timer = new Array();
jQuery('a').each(function($) {
    i++;
    timer[i] = setTimeout(jQuery(this).remove(), i * 5000)
})

Ответы [ 5 ]

8 голосов
/ 10 января 2012

Обернуть удалить элемент с функцией

i = 1;
var timer = new Array();
jQuery('a').each(function($) {
    i++;
    var thiz = jQuery(this);
    timer[i] = setTimeout(function() { thiz.remove(); }, i * 5000);
})
4 голосов
/ 10 января 2012

Первый параметр setTimeout (или setInterval) должен быть ссылкой на функцию (или строку, но вы не хотите использовать строковый синтаксис).

ВместоПередав функцию в качестве параметра, вы вызываете функцию и передаете ее результат.Если вы удалите скобки, вы передадите ссылку на функцию:

timer[i] = setTimeout(jQuery(this).remove, i * 5000) 

Но тогда у вас начнутся проблемы с this, который будет неправильным во время выполнения функции.Попробуйте что-то вроде этого:

var i = 1,
    timer = [];
jQuery('a').each(function($) {
    i++;
    var $this = jQuery(this);
    timer[i] = setTimeout(function() {$this.remove();}, i * 5000)
})

Это использует преимущества работы замыканий в том, что анонимная функция, переданная в setTimeout, будет иметь доступ к переменной $this во время ее запуска, даже еслифункция, в которой объявлено $this, к тому времени завершит выполнение.

Обратите внимание, что лучше объявить массивы с [], чем new Array().

Обратите внимание, что вы инициализируете i до 1, затем увеличьте его перед использованием, чтобы первый элемент, который вы добавили в ваш массив, был timer[2].Вам, вероятно, следует инициализировать его равным 0, а затем увеличивать его после установки каждого таймера.

3 голосов
/ 10 января 2012

Феликс уже намекал на проблему в комментариях, но я буду расширяться.

timer[i] = setTimeout(jQuery(this).remove(), i * 5000)

Ваша проблема заключается в том, что вы вызываете jQuery(this).remove() и передаете возвращаемое значение этого вашему setTimeout. Предполагается, что вы собираетесь запустить его по истечении времени ожидания. Если это так, вам нужно обернуть это в функцию, чтобы функция передавалась в setTimeout и выполнялась по истечении таймера.

var $el = jQuery(this);

timer[i] = setTimeout(function(){
    $el.remove()
}, i * 5000)
0 голосов
/ 10 января 2012

попробовать:

<html>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<a href="#">a</a>
<a href="#">a</a>
<a href="#">a</a>
<a href="#">a</a>
<a href="#">a</a>
<a href="#">a</a>
<script>
i = 1;
var timer = new Array();
    jQuery('a').each(function($) {
    i++;
    timer[i] = setTimeout(jQuery.proxy(function(){jQuery(this).remove();},this), i * 500);
})
</script>
</body>
</html>
0 голосов
/ 10 января 2012

setTimeout принимает операторы JavaScript, а не возвращаемое значение jQuery(this).remove(): P Смотрите эту ссылку

Вы можете просто function(){stuff}, но не уверены, будет ли jQuery(this) обрабатываться, когда вы этого хотите.

...