Skip to content Skip to sidebar Skip to footer

Creating A Grid Of Images With Jquery

I'm very new to web programming and jQuery. I want to load images and arrange them in a grid. However, the number of images to be loaded is not fixed. I have an array, img_arr, wit

Solution 1:

Mwahaha! [Evil laughter]

There's an error here, a common, insidious error, one that has nothing to do with images, or CSS, or jQuery. It's the late-binding error in Javascript.

The OP uses the variables t and l to mean "top" and "left" (incidentally, OP, what is wrong with top and left as variable names), incrementing them in a loop and invoking them at a callback. But t and l are late bound. When the onload functions are called, those variables are set to their final values, not the values they had when the image tag was created.

And so, "the images get placed on top of each other at the final offset location".

Try this:

var renderImage = function(imgdesc, t, l) {
   var img = newImage();
    $(img)
        .attr('src', imgdesc['url'])
        .attr('id',  imgdesc['id'])
        .load(function(){
            $('#container').append( $(this) );
            // Your other custom code
            $(this).css( {
                "position": "absolute",
                     "top": t + 'px',
                    "left": l + 'px'
            });
        });
};

var t = 0;
var l = 0;
for (i = 0; i < img_arr.length; i++) {
    renderImage(img_arr[i], t, l)
    l = l + 50;
    if (l > 300) {
        t = t + 50;
        l = 0;
    }
}

Solution 2:

If you don't NEED to position them absolutely, you could use a flow layout to accomplish this much more easily.

See this fiddle for an example. If you change the CSS for the width of #container you will see the number of images in each row change dynamically. I think this is a much cleaner approach. It takes all the math out and lets the browser handle laying things out.

Solution 3:

Lots of little inefficiencies in your code. For one use your jQuery, no need to do new Image() when you can just do $('<img />'). Also, probably at some point someone will want to change the number of images across, or the height of the images, give yourself an out there. Also, you can set multiple tag attributes at once using .attr({ ... }), and remember that jQuery comes with the very nice .each() method for dealing with regular arrays.

So here's my solution:

var numberAcross = 6,
    widthOfImages = heightOfImages = 50;

$.each(img_arr, function(idx, value){
    $('<img />').attr({
        'src': value.url,
        'id': value.id,
        'width': widthOfImages,
        'height': heightOfImages
    }).css({
        'position': 'absolute',
        'top':  Math.floor(idx  / numberAcross) * heightOfImages,
        'left': (idx * widthOfImages) % (numberAcross * widthOfImages)
    }).appendTo('#container');
});

Also, you might want to add css to your #container element so you can see a bit better while developing:

<style>#container {
    width: 100%;
    height: 600px;
    background-color: #ccc;
    position: relative;
}
</style>

Note that the position: relative in there means that wherever you put that "container" your absolutely positioned items will appear correctly.

Solution 4:

Not sure why they wouldn't fold properly actually. I'm pretty sure there are some nifty css-tricks you could use to set those positions in a css-file, but let's work with your sample.

Could it be that the container isn't tall enough to contain the additional rows and thusly just place it at the end?

As for your sample, I'd place the math inline, and for 6 images pr row simply do the following instead of using all those counting variables:

$(this).css( {
    "position": "absolute",
    "top": Math.floor(i / 6) * 50 + 'px',
    "left": (i % 6) * 50 + 'px'
});

It probably won't solve your problem, but it looks cleaner to my eye.

Post a Comment for "Creating A Grid Of Images With Jquery"