开发者

Jquery having trouble positioning images

开发者 https://www.devze.com 2023-02-09 17:56 出处:网络
Follow on from: Javascript wait for image to load before calling Ajax function initResources() 开发者_运维问答{

Follow on from:

Javascript wait for image to load before calling 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);
    }
}

I have an array of images. When the page is loaded initially from the server, this function loops through all the images and places them on the page.

This function is also called when the scale of the page changes. The scaling function clears the HTML and redraws everything with the scale multiplier.

The problem with this function, is that it always alerts resourceData.length, which is the end of the loop. I need to somehow pass data to the load function, so that when the image does finally load, it is referencing the correct ID/i.


You have a single i variable which is shared among all of your callbacks.

Since the callbacks execute asynchronously, they will all execute after the loop finishes, when i is length.

You need to put the loop body into a separate function that takes i as a parameter.
This way, each load callback will use a separate i variable (the function parameter), which will never change.


You can use a $.each() loop to create the closure (into which that index is it's own variable, not shared) you need...and the .position() call needs a bit of change as well, you should use .css() here which takes an object, like this:

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);
    });
}

You can shorten this up more, but it'll be no more efficient. Keep in mine that inside the .load() event handler you can refer to the element the handler is for with this, no need to select it again.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号