Как использовать переменные в функции обратного вызова imagesLoaded?

Я пытаюсь сделать что-то очень простое, но, очевидно, я делаю что-то не так. Вот код:

var targets = Array(
    $('.someDiv'),
    $('.myDiv')
    );
// This "for" loop check if the Class exists and if so it runs a code
for (var i = targets.length - 1; i >= 0; i--) {
    // make the target a jQuery object
    var $target = targets[i];
    // if the target exists
    if ( $target.length > 0 ) 
    {
        console.log($target);
        // run some code after every image is loaded
        $target.imagesLoaded( function()
        {
            console.log($target);
            $target.addClass('blue');
        });
    }
}

который как-то не работает. Пример JsFiddle здесь

Просто невозможно передать переменную без взлома плагина imagesLoaded? Или я что-то упустил?

3 ответа

Решение

Если вы хотите, чтобы переменная сохранила значение, которое она имела при вызове imagesLoaded()Вы можете использовать IIFE:

var myVar = 'someContent';

(function(myVar) {
    $('.myDiv').imagesLoaded( function() {
        console.log(myVar);
    });
})(myVar);

Возьмите этот пример:

var myVar = 'some content';

(function(myVar) {
    setTimeout(function() {
        console.log(myVar);
    }, 1000);
})(myVar);

myVar = 'some other content';
console.log(myVar);

Будет лог some other content а потом, чуть позже some content, как было первоначальное значение.

Хорошие новости: ваш код работает!

var myVar;
$('.myDiv').imagesLoaded( function() {
    console.log(myVar);
});

myVar является undefined как вы не определили это.

... пытаться var myVar = "Hello World";

Проблема в том, что imagesLoaded обратный вызов запускается после того, как вы уже перебрали элементы. Это означает, что к тому времени, когда первый обратный вызов срабатывает, $target является ссылкой на последний элемент в массиве.

К счастью, поскольку вы просто пытаетесь получить ссылку на элемент, который imagesLoaded Вы можете получить ссылку на него с помощью this,

Обновленный пример

var targets = [$('.someDiv'), $('.myDiv')];

for (var i = 0; i < targets.length; i++) {
    var $target = targets[i];

    if ($target.length) {        
        $target.imagesLoaded(function () {
            $(this).addClass('blue');
        });
    }
}

Кроме того, вы также можете использовать $.each() функция для сохранения контекста на каждой итерации:

Обновленный пример

var targets = [$('.someDiv'), $('.myDiv')];

$.each(targets, function (i) {
    var $target = targets[i];

    if ($target.length > 0) {
        $target.imagesLoaded(function () {
            $target.addClass('blue');
        });
    }
});
Другие вопросы по тегам