Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Javascript to load some images last

Hi I just wondered if this is possible. I have quite a few images on my website and I have made them as small file size as possible. Some of the images are used as a slideshow but there are all loaded in one go. Is there a way using javascript to make the slideshow images load last so that the background images etc load up first and the slideshow loads at the end. The images are in the main body of the page and are "slideshowified" using javascript. The code for this images is simple:

<div id="pics">
        <img src="images/cs9.png" width="270px" height="270px" alt="teaching"/>
            <img src="images/cs1.png" width="200px" height="200px" alt="teaching"/>
            <img src="images/cs3.png" width="200" height="200px" alt="teaching"/>

            <img src="images/cs5.png" width="200" height="200px" alt="teaching"/>
            <img src="images/cs6.png" width="200" height="200px" alt="teaching"/>
            <img src="images/cs7.png" width="200" height="200px" alt="teaching"/>
            <img src="images/cs4.png" width="200" height="200px" alt="teaching"/>
           <img src="images/cs12.png" width="200" height="200px" alt="teaching"/>
           <img src="images/cs8.png" width="200" height="200px" alt="teaching"/>
            <img src="images/cs10.png" width="200" height="200px" alt="teaching"/>
            <img src="images/cs14.png" width="200" height="200px" alt="teaching"/>


        </div>

Any idea would be great

Thanks

like image 512
jamie holliday Avatar asked Dec 05 '22 03:12

jamie holliday


2 Answers

Edit - See the bottom of this answer, a much better idea came to me

Original Answer

Yes, totally possible. Others have noted plug-ins for doing this, which are great in that they come pre-tested and such, but if you want to do it yourself it's surprisingly easy. You add img elements to the DOM (document object model):

function addAnImage(targetId, src, width, height) {
    var img;

    img = document.createElement('img');
    img.src = src;
    img.style.width  = width  + "px";
    img.style.height = height + "px";
    target = document.getElementById(targetId);
    target.appendChild(img);
}

(I couldn't immediately recall how to set the alt attribute; it may well be img.alt = "...";)

Naturally you'll want to add some error checking to that. :-) So for one of your images, you want to add them to the pics div, so for example:

addAnImage('pics', 'images/cs12.png', 200, 200);

Set up a function to add your images and call it when the page is loaded (either using window.onload or whatever support your JavaScript library, if any, has for doing things a bit earlier than that). For instance, your load script might look like this (I don't typically use window.onload, but it's convenient for an example):

function pageLoad() {
    var images = [
        {src: "images/cs9.png", width: 270, height: 270, alt: "teaching"},
        {src: "images/cs1.png", width: 200, height: 200, alt: "teaching"},
        {src: "images/cs3.png", width: 200, height: 200, alt: "teaching"},
        // ..., make sure the last one *doesn't* have a comma at the end
    ];
    var index;

    // Kick start the load process
    index = 0;
    nextImageHandler();

    // Load an image and schedule the next
    function nextImageHandler() {
        var imgdata;

        imgdata = images[index];
        addOneImage('pics', imgdata.src, imgdata.width, imgdata.height);
        ++index;
        if (index < images.length) {
            window.setTimeout(nextImagePlease, 200);
        }
    }
}
window.onload = pageLoad;

On window load, that will load the first image and then schedule the next one to be loaded 200ms (a fifth of a second) later. When that happens, it'll schedule the next, etc., etc., until it's loaded all of the images.

JavaScript libraries like jQuery, Prototype, Closure, etc. typically have various helper functions for this sort of thing.

Updated answer

The above is fine, but it means that you have to completely change how you layout your pages, and you have to intermix content stuff (the image sources and sizes) with your JavaScript, etc. Blech.

How 'bout this: Make all of your image tags that are the same size refer to the same image:

<div id="pics">
    <img src="images/w270h270.png" width="270" height="270" alt="teaching"/>
    <img src="images/w200h200.png" width="200" height="200" alt="teaching"/>
    <img src="images/w200h200.png" width="200" height="200" alt="teaching"/>
...

These would be placeholders. Then, add data attributes to them with the real image source:

<div id="pics">
    <img src="images/w270h270.png" data-src="cs9.png" width="270" height="270" alt="teaching"/>
    <img src="images/w200h200.png" data-src="cs1.png" width="200" height="200" alt="teaching"/>
    <img src="images/w200h200.png" data-src="cs3.png" width="200" height="200" alt="teaching"/>
...

Attributes in the form data-xyz will be valid as of HTML5 (and they work today, they just don't validate).

Now the magic: Once the main load is completed, you walk through the img tags in the DOM, updating their src to make their data-src attribute:

function pageLoad() {
    var nodeList, index;

    // Get a NodeList of all of the images on the page; will include
    // both the images we want to update and those we don't
    nodeList = document.body.getElementsByTagName('img');

    // Kick-start the process
    index = 0;
    backgroundLoader();

    // Our background loader
    function backgroundLoader() {
        var img, src;

        // Note we check at the beginning of the function rather than
        // the end when we're scheduling. That's because NodeLists are
        // *live*, so they can change between invocations of our function.
        // So avoid going past what is _now_ the end of the list.
        // And yes, this means that if you remove images from
        // the middle of the document while the load process is running,
        // we may end up missing some. Don't do that, or account for it.
        if (index >= nodeList.length) {
            // we're done
            return;
        }

        // Get this image
        img = nodeList[index];

        // Process it
        src = img.getAttribute("data-src");
        if (src) {
            // It's one of our special ones
            img.src = src;
            img.removeAttribute("data-src");
        }

        // Schedule the next one
        ++index;
        window.setTimeout(backgroundLoader, 200);
    }
}
window.onload = pageLoad;

Again, you'll want to add error handling and that's completely untested, but fundamentally it should work.

like image 68
T.J. Crowder Avatar answered Dec 09 '22 16:12

T.J. Crowder


You can use a jquery Lazy Load plugin

like image 28
Josh Mein Avatar answered Dec 09 '22 16:12

Josh Mein