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

Background images aren't considered in load #29

Closed
facultymatt opened this issue Apr 4, 2012 · 37 comments
Closed

Background images aren't considered in load #29

facultymatt opened this issue Apr 4, 2012 · 37 comments

Comments

@facultymatt
Copy link

Not sure if this is a limitation or just hasn't been implemented... but it would be great if background images could be detected along with tags.

@darsain
Copy link
Collaborator

darsain commented Apr 4, 2012

I think this is way out of scope for this plugin. Plus there is not much usability for it, as background images don't affect almost anything.

@facultymatt
Copy link
Author

...it would still be useful in some cases. For example, I'm working on a project that loads different parallax instances using ajax. The parallax script (like most) uses background images. So, I need a way to detect when the bg images are all loaded so I can show the parallax ready to go instead of mid-load.

To get around this I wrote a small bit of js that gets all elements with bg images and creates a temp array of images. Then I initialize the plugin with this array, and when everything is loaded I just remove the array. Bg images are ready to go, like magic! Seems to work well... needs some cross browser testing though.

@darsain
Copy link
Collaborator

darsain commented Apr 5, 2012

The imagesLoaded plugin is meant to be an images loaded checker. Element backgrounds are a different issue.

Nevertheless I thought about it, and it would be a mess to implement that. Not a problem, but a mess with calling the plugin, there would have to be a new argument being passed, and that would create weird plugin calls for people that wish to use just deferred functionality, also we would have to re-evaluate arguments passed to callbacks, plugin would get substantially bloated, ...

I think that creating temporary image elements with background url's yourself, and then passing them to imagesLoaded is a better solution than messing and bloating the plugin with a feature that is not in its primary scope. It is a lot cleaner this way.

Or maybe I could create a stepchild plugin called backgroundsLoaded...

But maybe @desandro thinks differently :)

@desandro
Copy link
Owner

desandro commented Apr 5, 2012

I concur. This project is aimed at <img>. Detecting background images would really open up the scope of this project.

Closing as outside of scope. But enough people +1 this, maybe its worth reconsidering.

@desandro desandro closed this as completed Apr 5, 2012
@darcyclarke
Copy link

I'm happy to hear that this isn't going into the library itself. I think it's relatively easy to circumvent the issue by creating temporary images that use the background-image url as their src. The script below is what I used to include background-images into my .imagesLoaded() call.

var images = $('img, .bg-img');
$.each(images, function(){
    var el = $(this),
    image = el.css('background-image').replace(/"/g, '').replace(/url\(|\)$/ig, '');
    if(image && image !== '' && image !== 'none')
        images = images.add($('<img>').attr('src', image));
    if(el.is('img'))
        images = images.add(el);    
});
images.imagesLoaded();

@desandro
Copy link
Owner

@darcyclarke Thanks for the work-around :)

@alexanderdickson
Copy link

I hope this isn't considered bad form, but may I suggest something I knocked up that can do this? It's called waitForImages and it's not nearly as powerful as imagesLoaded, but should suit for developers who wish to know when images referenced in the CSS have been downloaded.

@desandro
Copy link
Owner

desandro commented Feb 7, 2013

@alexanderdickson Thank you for pointing to your solution!

@koenpunt
Copy link
Contributor

Based on @darcyclarke's method, but with match instead of 2 replace calls, and starting with a collection of all img and adding the background images to it, instead of looping over all and testing that images are indeed images.

var images = $('img');
$('.bg-img').each(function(){
  var el = $(this)
    , image = el.css('background-image').match(/url\((['"])?(.*?)\1\)/);
  if(image)
    images = images.add($('<img>').attr('src', image.pop()));
});
images.imagesLoaded();

@darcyclarke
Copy link

@koenpunt Looks good!

@dustinhorton
Copy link

would like to +1 adding it to the plugin.

would be really useful for large background images, especially since you can't fade in a background image (via css or jquery). wait till loaded, then unmask it (via fading an element covering it, fading in the element, scaling the size, whatever).

@jheftmann
Copy link

+1 here as well.

@andreyvolokitin
Copy link

+1.

Also - Wouldn’t images be loaded twice in @darcyclarke and @koenpunt method?

@darcyclarke
Copy link

@andreyvolokitin not really. If you're talking about whether imagesLoaded will load the images twice, no. Check out this JSFiddle for an example of how that works: http://jsfiddle.net/hSpbu/3/ If you look in your console, you'll see there's only 2 images being tracked.

If you're referencing the fact that we create a new <img> element for the CSS background-image's, then yes. There will be two references to the same image, technically. That said, the browser won't try and load the image twice, it's smart enough to know you're referencing the same image inside that new element as well as within your CSS and only try to fetch the asset once.

I think your only real concern should be that you get one callback for each image loaded on a page, and the little snippets @koenpunt and I put together solve that.

@searls
Copy link

searls commented Nov 18, 2013

👍 -- in my experience in the post-retina world, a great number of the heaviest images I run into are actually set as background-images

@jackyon
Copy link

jackyon commented Dec 17, 2013

+1 totally need this feature.

@casimirlancaster
Copy link

+1

I concur that the images with the largest file sizes are usually background images.

@astrotim
Copy link

+1

Loading large images in the context of a full screen layout with the CSS background-image property allows for flexibility via the background-size property (cover, for example), which is not possible via the img element. A use case is to delay the CSS animations of other elements in the layout until the background image has loaded. I will gladly give the @darcyclarke method a go in the absence of this feature.

In any case, love yer work, @desandro, especially Isotope.

@colinsullivan
Copy link

+1, I have a similar use case as described above, parallax bg images which are hi-res and heavy.

Thanks for the workaround!

@kennycrosby
Copy link

1+1=2

@Gwildor
Copy link

Gwildor commented Jul 31, 2014

I would like this feature as well, because using background-image allows for some extra features, such as transitions using the background-position and using background-size: cover. I've now used the above-mentioned waitForImages instead, and does that trick perfectly.

@koenpunt
Copy link
Contributor

A revised version of my code above, now with support for multiple backgrounds:

var $images = $('img');
$('.bg-img').each(function(){
  var el = $(this), sources, image;
  if(sources = el.css('background-image')){
    $.each(sources.split(','), function(i, source){
      if(image = source.match(/url\((['"])?(.*?)\1\)/)){
        $images = $images.add($('<img>').attr('src', image.pop()));
      }
    });
  }
});

Fiddle here: http://jsfiddle.net/koenpunt/xkwrbsru/

@dhritzkiv
Copy link

👍

@pruett
Copy link

pruett commented Nov 22, 2014

i'd like to +1 this as well,

given the flexibility of background images with regards to full width layouts, the ability to set multiple backgrounds, etc., I do think it's a worthwhile feature request. In the meantime it looks like some quality workarounds have been proposed in this thread.

thanks @desandro

@KingScooty
Copy link

+1

@arxpoetica
Copy link

I wonder that this shouldn't be reconsidered. A good share of use-cases for preloading images (especially in this parallax-heavy home page world) falls to background images. It doesn't have to be considered "out of scope" if the plugin is built to only test sources (http://...[filename][jpg/gif/png/whatever]). Maybe that needs to be a completely different library all together, but it would be a shame to have all the idiosyncrasies learned here go to waste on a greatly needed feature. sad panda

@matthewgovaere
Copy link

+1

@DonSanto
Copy link

+1

3 similar comments
@homerjam
Copy link

+1

@angelmeraz
Copy link

+1

@rob-gordon
Copy link

+1

@desandro desandro reopened this Aug 7, 2015
@nevace
Copy link

nevace commented Aug 25, 2015

+1

1 similar comment
@aryehraber
Copy link

+1

@desandro
Copy link
Owner

🎉 ⭐ 🌈 imagesLoaded v3.2.0 now supports background images 🌈 ⭐ 🎉 Try it out!


Set { background: true } to detect when the element's background image has loaded.

// jQuery
$('#container').imagesLoaded( { background: true }, function() {
  console.log('#container background image loaded');
});

// vanilla JS
imagesLoaded( '#container', { background: true }, function() {
  console.log('#container background image loaded');
});

Set to a selector string like { background: '.item' } to detect when the background images of child elements have loaded.

// jQuery
$('#container').imagesLoaded( { background: '.item' }, function() {
  console.log('all .item background images loaded');
});

// vanilla JS
imagesLoaded( '#container', { background: '.item' }, function() {
  console.log('all .item background images loaded');
});

@nevace
Copy link

nevace commented Oct 29, 2015

Amazing, thanks!

@arxpoetica
Copy link

++++AWESOME!!!

@desandro
Copy link
Owner

I'm closing this issue as resolved. If you run into an issue with imagesLoaded and background images, please open a new issue.

Repository owner locked and limited conversation to collaborators Nov 30, 2015
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