I have got the bootstrap carousel working on my web page and i want it to lazy load.
I have found this piece of code on the internet:
$("#myCarousel").bind("slid", function(){
$img = $(".active img", this);
$img.attr("src", $img.data('lazy-load-src'));
});
This causes the carousel to "load" the current image when the next button (or prev) button is clicked. I want it to load not the current image but the image after that, and the image in front of the current image, so that i still have the nice sliding animation. And not a loading image.
So my question is how do I set the lazy-load-src to src of the previous image and of the next image when the next button is clicked?
There are several options, depending on the precision you need, but you should keep the lazy-load-src
to their own img
tags.
You can use selectors, put in data-
attributes and use that to select your next image to load. But this is messy.
I think your best shot is using the .next()
method on your items, so that on slid
you load the next image. Something like :
$('#myCarousel').on('slid', function() {
var $nextImage = $('.active.item', this).next('.item').find('img');
$nextImage.attr('src', $nextImage.data('lazy-load-src'));
});
I've updated Sherbrows answer a bit to support Bootstrap v3 and a random start index. I'm using a page of thumbnails. When a user clicks a thumb, the carousel should start at that index.
Show the carousel
function showGallery(startIndex) {
//Load first and second image
var imageElement = $('#fullscreengallery .item:nth-child(' + (startIndex + 1) + ') img');
imageElement.attr('src', imageElement.attr('data-lazy-load-src'));
imageElement = $('#fullscreengallery .item:nth-child(' + (startIndex + 2) + ') img');
imageElement.attr('src', imageElement.attr('data-lazy-load-src'));
//Init carousel
$('#fullscreengallery').carousel(startIndex);
//Show carousel
$('#fullscreengallery').removeClass('hidden');
};
Do lazy loading
$('#fullscreengallery').on('slid.bs.carousel', function() {
//Lazy load
var nextImage = $('.active.item', this).next('.item').find('img');
//If no next, select first
if(nextImage.length === 0){
nextImage = $('#fullscreengallery .item:nth-child(1) img');
}
//Set the source if it hasn't been set already
if (!nextImage.attr('src')) {
nextImage.attr('src', nextImage.attr('data-lazy-load-src'));
}
});
I took Arnoud Sietsema's answer a step further. The images in your carousel could have loading gifs to begin with. Then...
Show the carousel
function showGallery(startIndex) {
//Load first, second and last image
var imageElement = $('#fullscreengallery .item:nth-child(' + (startIndex + 1) + ') img');
imageElement.attr('src', imageElement.attr('data-lazy-load-src'));
imageElement.attr('data-loaded', '1');
imageElement = $('#fullscreengallery .item:nth-child(' + (startIndex + 2) + ') img');
imageElement.attr('src', imageElement.attr('data-lazy-load-src'));
imageElement.attr('data-loaded', '1');
imageElement = $('#myCarousel .item:last img');
imageElement.attr('src', imageElement.attr('data-src'));
imageElement.attr('data-loaded', '1');
//Init carousel
$('#fullscreengallery').carousel(startIndex);
//Show carousel
$('#fullscreengallery').removeClass('hidden');
};
Do lazy loading
$('#fullscreengallery').on('slid.bs.carousel', function() {
//Lazy load
var nextImage = $('.active.item', this).next('.item').find('img');
//If no next, select first
if(nextImage.length === 0){
nextImage = $('#fullscreengallery .item:nth-child(1) img');
}
//Set the source if it hasn't been set already
if (nextImage.attr('data-loaded') == '0') {
var $downloadingImage = $("<img>");
$downloadingImage.load(function(){
nextImage.attr("src", $(this).attr("src"));
nextImage.attr('data-loaded', '1');
});
$downloadingImage.attr("src", nextImage.attr('data-src'));
}
var prevImage = $('.active.item', this).prev('.item').find('img');
//If none, select last
if(prevImage.length === 0){
prevImage = $('#myCarousel .item:last img');
}
//Set the source if it hasn't been set already
if (prevImage.attr('data-loaded') == '0') {
var $downloadingImage = $("<img>");
$downloadingImage.load(function(){
prevImage.attr("src", $(this).attr("src"));
prevImage.attr('data-loaded', '1');
});
$downloadingImage.attr("src", prevImage.attr('data-src'));
}
});
The difference is that, when trying to load the next slide, it's first loaded 'under the hood', and, only when loaded, inserted into the carousel. As a result, the loading image is shown until the image is fully loaded.
Also, the carousel can now be moved in both directions.