Skip to content
This repository has been archived by the owner on Sep 6, 2022. It is now read-only.

Event after picturefill is finished switching the images? #664

Closed
katerlouis opened this issue Jul 28, 2016 · 9 comments
Closed

Event after picturefill is finished switching the images? #664

katerlouis opened this issue Jul 28, 2016 · 9 comments

Comments

@katerlouis
Copy link

katerlouis commented Jul 28, 2016

I use responsive images inside a slider created with swiper.
http://idangero.us/swiper/#.V5o4f1dshE4

This plugin calculates the height for the first shown element and then has a "autoHeight" option for the next slides to come. Pretty cool.

I like art direction and therefore have different heights on my responsive images.
The fallback / default for instance in most cases is a 17:15 aspect ratio. The image gets wider with higher viewport.

<picture>
    <source srcset="/test_desktop.jpg 1x, /test_desktop@2x.jpg 2x" media="(min-width: 800px)" />
    <source srcset="/test_tab.jpg 1x, /test_tab@2x.jpg 2x" media="(min-width: 500px)" />

    <img srcset="/test_phone.jpg" alt="" />
</picture>

Problem now:
Swiper calculates the height with the initial aspect ratio of the phone image.
After swiper got its height picturefill.js switches out the image.
Strange is: roughly 8 of 10 times picturefill.js is faster than swiper and the problem doesn't occur.
But those 20% are worth recalculating after picturefill is finished.

My question:
How can I execute code after picturefill has done its thing?

PS: I'm open to suggestions for different solutions.

@mike-engel
Copy link
Collaborator

Have you tried .onLoad on the image?

@katerlouis
Copy link
Author

katerlouis commented Jul 29, 2016

What exactly do you mean?

$("img").on("load" ...) 

?

@mike-engel
Copy link
Collaborator

@katerlouis Yeah, that event should be emitted when an image is loaded

@katerlouis
Copy link
Author

But that is not exactly my what I want–
I'm not sure right now if there is a guarantee that picturefill is always finished before the images are loaded? Which image I check on with the onLoad solution? The phone one? The biggest desktop one?

It would be way cleaner if picturefill would fire an event when it's done.
Your reply makes me feel there is not such thing yet.

Let's do one! :)

@aFarkas
Copy link
Collaborator

aFarkas commented Jul 29, 2016

@katerlouis
I don't think that this is a picturefill issue at all. It's an issue of the swiper plugin. Does your problem (also) happen in current versions of Safari, Chrome, Firefox or Edge. If that is the case, than it is pretty clear, that picturefill isn't even involved in any way.

You can also see some discussion about possible workarounds here:
http://github.com/desandro/imagesloaded/issues/175#issuecomment-86964276

The pattern I describe there would look something like this with the swiper plugin:

$('.swiper').each(function(){
    var swiper = new Swiper(this, {
        speed: 400,
        spaceBetween: 100
    });

    var update = function(){
        //less obtrusive: swiper.updateContainerSize();
        swiper.update();
    };

    this.addEventListener('load', update, true);
});

@katerlouis
Copy link
Author

katerlouis commented Jul 29, 2016

I use Safari 9.1.1.
I thought this version still doesn't support native responsive images?
If they are supported swiper, which is JS, should get only the image with the correct height for this breakpoint to calculate with, or am I wrong in that thinking? (> IF native responsive images do work)

The workaround looks nice;
But do you really think it would cause a reflow even for native responsive images¿?

@aFarkas
Copy link
Collaborator

aFarkas commented Jul 30, 2016

I use Safari 9.1.1.
I thought this version still doesn't support native responsive images?

It fully supports responsive images. see http://caniuse.com/#search=picture

If they are supported swiper, which is JS, should get only the image with the correct height for this breakpoint to calculate with, or am I wrong in that thinking? (> IF native responsive images do work)

Swiper does not take a special image height, swiper tries to wait until the image(s) are loaded and then re-calculates the height of the swiper cells. For this task: Swiper seems to only handle img.src and img.srcset (the later only if img.src is also present). Which seems really broken. (see: https://github.com/nolimits4web/Swiper/blob/master/dist/js/swiper.js#L508-L531) The technique, they use is similar to the imagesloaded one.

I wouldn't use this technique anymore.

But do you really think it would cause a reflow even for native responsive images¿?

Most sliders produce reflows and swiper does this also. The JS workaround above will also additionally produce reflows, if you want to minimize reflows you need to solve this with CSS. In case of picture, this is a little bit more work. How you can achieve this was also described in the imagesloaded issue: desandro/imagesloaded#175 (comment)

@katerlouis
Copy link
Author

Thank you guys for the detailed information on that matter.
I use the opportunity to ask again, just to be really sure.

You say my Safari supports picture. Every source inside one slider has the exact same dimensions. And still you say that swiper could cause a reflow there? I don't understand that– yes: swiper waits fo all the images to load; but as said they have the same dimensions. Why would the initial slide be the height of the (assumingly) phone images dimension?

Could this have to do something with the lack of an src-attribute in my markup? I only use srcset on the img-tag inside the picture-tagg, like picturefill suggests.

@yairEO
Copy link

yairEO commented Dec 26, 2016

Maybe try adding to the img a blank empty image data:

src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants