I've modified Visual Idiot's Unslider (http://unslider.com/) to accommodate multiple-width slides based on image proportions, but in the process, I've encountered a bug which causes slides to load as tiny thumbnails (I think in the case where the images haven't loaded all the way). That's problem #1. So I'm trying to wait until all images are loaded. But I haven't found a way to do that successfully. That's problem #2.
Here is my added code inside the Unslider init() function:
_.init = function(el, o) {
// Check whether we're passing any options in to Unslider
_.o = $.extend(_.o, o);
_.el = el;
_.ul = el.find(_.o.items);
_.max = [el.outerWidth() | 0, el.outerHeight() | 0];
_.max = [100, 100];
_.li = _.ul.find(_.o.item).each(function(index) {
var me = $(this);
var an_image = me.find('img');
an_image.load(function() {
width = an_image[0].naturalWidth,
height = an_image[0].naturalHeight;
setSlideHeight(an_image, width, height, 300, 20);
if ( an_image.parent().parent().is(":last-child") ) {
_.el.css("width", 900);
}
})
// Set the max values
//if (width > _.max[0]) _.max[0] = width;
//if (height > _.max[1]) _.max[1] = height;
});
And here is my Ruby partial with a script inline for triggering Unslider when all the images are loaded.
<% if @page.cap_gallery_images.any? %>
<script>
$(document).ready(function() {
var numLoaded = 0;
var numToLoad = $('#gallery img').length;
alert("To Load: " + numToLoad);
$('#gallery img').load(function(){
numLoaded += 1;
alert("Loaded: " + numLoaded);
if (numLoaded == numToLoad) {
var gallery = $('#gallery').unslider(),
data = gallery.data('unslider');
data.to(0);
}
});
$("#slidecontainer .slide a").click(function(e) {
destination = $(this).parent().index();
data.to(destination);
e.preventDefault;
});
$(window).scroll(function() {
checkGalleryAgainstLogo();
});
$(window).resize(function() {
checkGalleryAgainstLogo();
});
checkGalleryAgainstLogo();
$('#logo.small').addClass('white');
});
</script>
<% end %>
The issue is that it looks like the image loading handlers aren't all triggering. Look at it in context on the page I'm using it on: http://penumbra-2.herokuapp.com/education
Regarding #2: I think youve made this too complex. You don't have to check on the individual img
assets like you're doing; you really just want to know when the entire gallery has loaded, so make your life simple:
$('#gallerycontainer').load(function(){
$('#gallery').unslider();
}
});
Your might want to add the HTML into your question so people know how to target the jQuery:
<div id="gallerycontainer">
<div id="gallery">
<div id="slidecontainer">
<div class="slide">
<a href="#"><img /></a>
</div>
</div>
</div>
</div>
The load event is sent to an element when it and all sub-elements have been completely loaded. .load
is what you need. An advantage of using this is that you can attach this to a subset of DOM. If you have a images in a division like this
<div class="slider">
<img src="image1.jpg"/>
<img src="image2.jpg"/>
<img src="image3.jpg"/>
</div>
Now you can use .load just on the slideshow container if all the images have loaded.
$('.slider img').load(function(){
//Your code goes here
});
CAUTION : If you are using jQuery 1.8, this has been deprecated.
You can use .on with appropriate arguments
e.g .on('load', handler)
I can see two different solutions on this, and depends on what's your objective.
On the code you're using $(document).ready();
which triggers when the DOM is ready, and not when the assets are totally downloaded, so makes sense to to detect when the image are loaded, but in this case I'd go for use the native Image() object and avoid using .load()
as I found it extremely unreliable in several occasions, and as far as I know also sometimes it does not trigger perfectly if the images are loaded from the browser cache.
$('#gallery img').each(function() {
var currentimage = new Image();
currentimage.src = this.src;
currentimage.onload = function(){
numLoaded += 1;
alert("Loaded: " + numLoaded);
if (numLoaded == numToLoad) {
var gallery = $('#gallery').unslider(),
data = gallery.data('unslider');
data.to(0);
}
};
});
Another solution (which I'll prefer to use here) is to use window.onload
which triggers when your document and assets are fully downloaded, and you should use it in that way:
window.onload = function(){
// Initialise your slider here
}
Try this (pattern)
html
<!-- load images container, images with document, `display:none` -->
<div id="slidecontainer" style="display:none;">
<div class="slide"> <a href="#">
<img alt="Chemistry-1" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/chemistry-1.jpg" />
</a>
</div>
<div class="slide"> <a href="#">
<img alt="Hamilton" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/Hamilton.jpg" />
</a>
</div>
<div class="slide"> <a href="#">
<img alt="Platinum6" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/platinum6.jpg" />
</a>
</div>
<div class="slide"> <a href="#">
<img alt="Lectures-1-2" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/lectures-1-2.jpg" />
</a>
</div>
<div class="slide"> <a href="#">
<img alt="Lenses-1-2" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/lenses-1-2.jpg" />
</a>
</div>
<div class="slide"> <a href="#">
<img alt="Bromoil-1" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/bromoil-1.jpg" />
</a>
</div>
<div class="slide"> <a href="#">
<img alt="Platinum2-1" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/platinum2-1.jpg" />
</a>
</div>
<div class="slide"> <a href="#">
<img alt="Schaefer2" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/Schaefer2.jpg" />
</a>
</div>
<div class="slide"> <a href="#">
<img alt="Classroom-1-2" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/classroom-1-2.jpg" />
</a>
</div>
<div class="slide"> <a href="#">
<img alt="Dagbeq_web" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/dagbeq_web.jpg" />
</a>
</div>
<div class="slide"> <a href="#">
<img alt="Carbon_schaefer" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/Carbon_Schaefer.jpg" />
</a>
</div>
</div>
<div id="gallerycontainer">
<div id="gallery" style="margin-top: 67px;"></div>
</div>
js
// hold jquery `ready` `event`
$.holdReady(true);
// load images container, images into `slider` container
$("#gallery").load(document.location.href + " #slidecontainer",
function(data, textStatus, jqxhr) {
// if all images loaded (11), document.ready, release `holdReady`
return ($("#gallery img").length === 11
&& $.isReady
&& jqxhr.state() === "resolved"
? $.when($.holdReady(false)).done(function() {
alert($.isReady);
$("#slidecontainer").css("display", "block");
// images appended to document,
// do (`slider`) stuff
})
: alert(!$.isReady) )
});
jsfiddle http://jsfiddle.net/guest271314/tLca3/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With