Change loading order of images already on page
Asked Answered
E

3

3

Is there any way without AJAX of changing the loading order of images on a page? Or even a way to completely halt or pause loading of images already present?

The use case is simple - I have a long list of images down a page, and visitors will be landing on different spots of the page using URL anchors (/images#middle-of-page) that refer to actual containers for those images.

I'd like in the least to load the images inside the requested container FIRST, then continue loading the rest of the images.

The challenge is that there is no way to know the image paths of the requested container image before loading the page DOM.

I've tried getting the container img contents on load, then using the Javascript new Image() technique, but it doesn't change the fact that that image on the page will still be waiting for all previous images to load.

I've also tried immediately prepending a div in the body with a background image (CSS) of said img path, but this also does not prioritize the image load.

Any other ideas?

Eusebiaeusebio answered 26/10, 2011 at 17:16 Comment(6)
Nope. The browser will request the images in the order they appear in the HTML, but what order they arrive in is out of its hands.Cloudland
What about a way to instantly kill still-loading images? Or changing the order before they're processed?Eusebiaeusebio
@atwixor No, you need to look at AJAX solutions. HTML simply doesn't support this sort of thing.Cloudland
Maybe pre-loading the images before the user lands on the page?Alyce
Thanks - I'll take that as the answer then, @mblase75. As I'm wary to start on a from-scratch AJAX adventure (not really knowing the protocol), I think I may just fill the page with text image source paths, then use jQuery to transform them into <img> elements upon viewing.Eusebiaeusebio
@Alyce - If it weren't a Drupal website with MySQL mixed with a crazy Views jQuery slideshow plugin, I definitely would. Thanks though!Eusebiaeusebio
S
3

You need to have a DOM with empty img placeholders, i.e.

<img src="" mysrc="[real image url here]" />

Or you can make images to display "Loading..." image by default. You can even cache real image url in some custom tag, mysrc for example. Then once you know what exactly images you want to show (and in what order) you need to build a sequence of image loading

var images = [];//array of images to show from start and in proper order
function step(i){
  var img = images[i++];
  img.onload = function(){
    step(i);
  }
  img.src = "[some url here]"
}

Hope this helps.

Sick answered 26/10, 2011 at 17:38 Comment(3)
The custom attribute should probably be data-srcRaby
Thanks - I think this suits my case - I will test it out today.Eusebiaeusebio
This answer is better than I first understood it to be, so to spare anyone else from my misunderstanding, onload doesn't mean "wait until it has finished loading". I thought it did, and wrote a whole function to account for that, but no, this code behaves as needed without modification. Good job. Upvote earned.Aweinspiring
E
0

For interest, this is the function I ended up implementing based on the answers here (I made it an on-demand loading function for optimum speed):

function loadImage(img) { // NEED ALTERNATE METHOD FOR USERS w/o JAVASCRIPT! Otherwise, they won't see any images.

      //var img = new Image(); // Use only if constructing new <img> element

        var src = img.attr('alt'); // Find stored img path in 'alt' element

        if(src != 'loaded') {

          img

            .load(function() {
              $(this).css('visibility','visible').hide().fadeIn(200); // Hide image until loaded, then fade in
              $(this).parents('div:first').css('background','none'); // Remove background ajax spinner
              $(this).attr('alt', 'loaded'); // Skip this function next time
              // alert('Done loading!');
            })

            .error(function() {
              alert("Couldn't load image! Please contact an administrator.");
              $(this).parents('div:first').find("a").prepend("<p>We couldn't find the image, but you can try clicking here to view the image(s).</p>");
              $(this).parents('div:first').css('background','none');
            })

            .attr('src', src);
        }
    }
Eusebiaeusebio answered 7/11, 2011 at 15:37 Comment(0)
C
0

The img loading="lazy" attribute now provides a great way to implement this.

With it, images load automatically only when on the viewport. But you can also force them to load by setting in the JavaScript:

document.getElementById('myimg').loading = 'eager';

I have provided a full runnable example at: How do you make images load lazily only when they are in the viewport?

One really cool thing about this method is that it is fully SEO friendly, since the src= attribute contains the image source as usual, see also: Lazy image loading with semantic markup

Cohabit answered 22/4, 2020 at 6:50 Comment(1)
But if you'd like the following to happen: 1. the viewport images are loaded first 2. once all viewport iamges are loaded, load the rest of the images (even if they are not visible yet), loading="lazy" wouldn't do that, no?Redhot

© 2022 - 2024 — McMap. All rights reserved.