Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workaround/Idea: Preloading images with srcset attributes (chrome) #166

Closed
rs3d opened this issue Oct 22, 2014 · 8 comments
Closed

Workaround/Idea: Preloading images with srcset attributes (chrome) #166

rs3d opened this issue Oct 22, 2014 · 8 comments

Comments

@rs3d
Copy link

rs3d commented Oct 22, 2014

Hi,
I'm working on a mobile app and was searching for a solution to preload the "current" image when an image has the srcset attribute (for calculating it's container height).
I had many issues on chrome/win and resolved them by using the img property 'currentSrc'.

Because there was no event, when currentSrc has been set by chrome (I was testing many timeout values), I choose following approach:

function waitForComputedSrcset (images, $dfd) {
    $dfd = $dfd || $.Deferred();

    var computed = 0,
        length = images.length;

    for (var i = 0; i < length; i++) {
        if (images[i].hasOwnProperty('currentSrc') && !! !images[i].currentSrc) {
            window.setTimeout(this.waitForComputedSrcset.bind(this, images, $dfd), 100);
            return $dfd;
        }
        computed++;
    }
    return (length === computed) ? $dfd.resolve(images) : $dfd;
}

When all images are "computed" by chrome I set all src properties of the resolved images to
var length = images.length;
for (var i = 0; i < length; i++) {
if (images[i].hasOwnProperty('currentSrc') && !! !images[i].currentSrc) {
images.src = images[i].currentSrc;
}
}

I'm not sure if this is a solution to the specs, but so I've got it working and imagesloaded doesn't load the wrong images initially. Imo/Hopefully only browsers, which are supporting the srcset attribute are setting img.currentSrc.

@PavelCherkashinCreuna
Copy link

@rs3d Thanks, it works fine for me. Btw: is there any good reason to use 100ms in setTimeout? Because it works fine with 0ms for me.

@desandro
Copy link
Owner

Unfortunately, I haven't tackled srcset with imagesLoaded. Thank you for sharing your insights here.

@rs3d
Copy link
Author

rs3d commented Jan 12, 2015

Hi @Ppavell, when I was using currentSrc, it wasn't computed on pageload. I used 100ms to save cpu performance. With 0ms waitForComputedSrcset is called very often. Insert a console.log and try some different timeouts to see the difference.

@hatsumatsu
Copy link

Hi @rs3d, your workaround seems to be a perfect solution for #175 . Could you give us a more detailed example of how to use your function in combination with a regular imagesLoaded workflow? Thanks!

@rs3d
Copy link
Author

rs3d commented Feb 3, 2015

Hi @hatsumatsu, here is a rough pen: http://codepen.io/rawbitz/pen/WbZMem (only tested in Mac/Chrome 40)
Every 50ms waitForComputedSrcset is looking for the currentSrc property.
If finished all image.src properties are updated and imagesLoaded can be run.

@hatsumatsu
Copy link

Thanks @rs3d, I'll give it a try, looks very promising!

@cywtf
Copy link

cywtf commented Feb 18, 2015

The workaround from @rs3d is doing the trick now for me. It's loading fine in Chrome 40 (PC)

@hayatbiralem
Copy link

Hi,

I did not find a solution with imagesLoaded for my issue than I wrote a simple function with some jQuery improvemens. That works for me now without imagesLoaded library:

My Pen: http://codepen.io/hayatbiralem/pen/jbjLZe?editors=001
Original Pen: http://codepen.io/desandro/pen/bIFyl

var imagesLoaded = function(selector, onComplete, onProgress) {
  var $images = $(selector).find('img');
  var success = 0;
  var error = 0;
  var iteration = 0;
  var total = $images.length;
  var check = function(el, status) {
    iteration++;
    var data = {
      img: el,
      iteration: iteration,
      success: success,
      error: error,
      total: total,
      status: status
    };
    $.isFunction(onProgress) && onProgress(data);
    if (success + error === total) {
      $.isFunction(onComplete) && onComplete(data);
    }
  };
  $images.each(function() {
    this.onload = function() {
      success++;
      check(this, 'success');
    };
    this.onerror = function() {
      error++;
      check(this, 'error');
    };
  });
};

@desandro desandro closed this as completed Feb 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants