JQuery имеет проблемы с позиционированием изображений - PullRequest
1 голос
/ 09 февраля 2011

Follow from:

Javascript ожидает загрузки изображения перед вызовом Ajax

function initResources() {

    var newImage;
    for (i = 0; i < resourceData.length; i++) {

        // Create the image
        newImage = $('<img alt="Big" id="imgA' + i + '" class="mediaImg" width="' + Math.round(resourceData[i][2] * currentScale) + '" height="' + Math.round(resourceData[i][3] * currentScale) + '" />');

        newImage.load(function() {

            alert(i);

            // Position
            $('#imgA' + i).position().top(Math.round(resourceData[i][5] * currentScale));
            $('#imgA' + i).position().left(Math.round(resourceData[i][4] * currentScale));

        });
        newImage[0].src = uploadFolder + '/' + imgData[resourceData[i][1]][1];
        $('#thePage').append(newImage);
    }
}

У меня есть массив изображений. Когда страница первоначально загружается с сервера, эта функция перебирает все изображения и размещает их на странице.

Эта функция также вызывается при изменении масштаба страницы. Функция масштабирования очищает HTML и перерисовывает все с помощью множителя масштаба.

Проблема с этой функцией в том, что она всегда оповещает resourceData.length, который является концом цикла. Мне нужно каким-то образом передать данные в функцию загрузки, чтобы, когда изображение наконец загружается, оно ссылалось на правильный идентификатор / i.

Ответы [ 2 ]

4 голосов
/ 09 февраля 2011

У вас есть одна переменная i, которая используется всеми вашими обратными вызовами.

Поскольку обратные вызовы выполняются асинхронно, все они будут выполняться после завершения цикла, когда i равно length.

Вам нужно поместить тело цикла в отдельную функцию, которая принимает i в качестве параметра.
Таким образом, каждый обратный вызов load будет использовать отдельную переменную i (параметр функции), который никогда не изменится.

3 голосов
/ 09 февраля 2011

Вы можете использовать цикл $.each() для создания замыкания (для которого этот индекс является собственной переменной, не разделяемой), в которой вы нуждаетесь ... и .position() вызов также нуждается в небольшом изменении, вы должны использовать .css() здесь, который принимает объект, например так:

function initResources() {
    var newImage;
    $.each(resourceData, function(i, data) {
       newImage = $('<img alt="Big" id="imgA' + i + '" class="mediaImg" width="' + Math.round(data[2] * currentScale) + '" height="' + Math.round(data[3] * currentScale) + '" />');
       newImage.load(function() {
            $(this).css({ top: Math.round(data[5] * currentScale), 
                         left: Math.round(data[4] * currentScale) });
       });
       newImage[0].src = uploadFolder + '/' + imgData[data[1]][1];
       $('#thePage').append(newImage);
    });
}

Вы можете сократить этобольше, но это не будет более эффективным.Имейте в виду, что внутри обработчика событий .load() вы можете ссылаться на элемент, для которого этот обработчик используется с this, нет необходимости выбирать его снова.

...