bootstrap 3 - need to preload images for a bootstrap modal carousel

Go here: http://ikonltd.com/artists/baldessari/

Click on any of the thumbs and the modal carousel will pop up. The issue is that sometimes it is not populated with the image and the caption. Sometimes it is. It seems to be a preload issue, but every preload script I've tried doesn't work. Then, I got into lazy load, but that doesn't do the trick either.

My carousel images are dynamically generated and sometimes there can be 25 per page. So, I need to ensure that everytime my modal carousel opens, it will be populated with the corresponding image and caption.

I'm currently not preloading on the page example. But I am attempting to use lazy load. Here's my modal, carousel & lazy load scripts (which I have at the bottom of the code)

<script type="text/javascript">
 /* copy loaded thumbnails into carousel */
$('.row .thumbnail').click(function(e){
  
}).each(function(i) {
  if(this.complete) {
  	var item = $('<div class="item lazy-load"></div>');
    var itemDiv = $(this).parents('div');
    var title = $(this).parent('a').attr("title");
    
    item.attr("title",title);
  	$(itemDiv.html()).appendTo(item);
  	item.appendTo('.carousel-inner'); 
    if (i==0){ // set first item active
     item.addClass('active');
    }
  }
});

/* activate the carousel */
$('#modalCarousel').carousel({interval:false});

/* change modal title when slide changes */
$('#modalCarousel').on('slid.bs.carousel', function () {
  $('.modal-title').html($(this).find('.active').attr("title"));
})

/* when clicking a thumbnail */
$('.row .thumbnail').click(function(){
    var idx = $(this).parents('div').index();
  	var id = parseInt(idx);
  	$('#myModal').modal('show'); // show the modal
    $('#modalCarousel').carousel(id); // slide carousel to selected
  	
});

    </script>
    
<script type="text/javascript">
jQuery(window).load(function() { // wait for complete page loading with image
     jQuery('.carousel').find('img').not(":first").each(function(i, v) { // for each image inside the carousel (the element with .carousel class)
          var src = jQuery(this).attr("src"); // put the src value for each image in variable
          //alert(src);  remove this line if the script work fine 
          jQuery(this).attr("data-lazy-load-src", src); // put this src value inside data-src
          jQuery(this).removeAttr("src"); // remove the src attribute
     });
});

  </script>    
  


      <script type="text/javascript">
$(document).ready(function() {
$(".swipeThis").swiperight(function() {
$(this).carousel('prev');
});
$(".swipeThis").swipeleft(function() {
$(this).carousel('next');
});
});
</script> 

  <script type="text/javascript">
var cHeight = 0;

$('#modalCarousel').on('slide.bs.carousel', function (e) {
        var $nextImage = null;

        $activeItem = $('.active.item', this);

        if (e.direction == 'left'){
            $nextImage = $activeItem.next('.item').find('img');
        } else {
			if ($activeItem.index() == 0){
                $nextImage = $('img:last', $activeItem.parent());
            } else {
                $nextImage = $activeItem.prev('.item').find('img');
            }
	    }

        // prevents the slide decrease in height
        if (cHeight == 0) {
           cHeight = $(this).height();
           $activeItem.next('.item').height(cHeight);
        }

        // prevents the loaded image if it is already loaded
        var src = $nextImage.data('lazy-load-src');
        
        if (typeof src !== "undefined" && src != "") {
           $nextImage.attr('src', src)
           $nextImage.data('lazy-load-src', '');
        }
    });
</script>

Open in new window

phillystyle123Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

phillystyle123Author Commented:
added a jquery preload script to this as well. So, even after the images are preloaded, they don't show up sometimes in the bootstrap modal carousel
Julian HansenCommented:
Did we not solve this in this post http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_28682375.html?

You still have this in your script
 if(this.complete) {

Open in new window

When that loop executes - if the image has not completed loading it is going to skip it - you need to remove the .complete - it is not necessary. The image does not have to be loaded to add the <img> tag to the carousel. They will show once the images have loaded.

A bit confused why the question seems to have gone backwards?
phillystyle123Author Commented:
When I remove that line random images load in the carousel
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

Julian HansenCommented:
Just for fun can you post your code with the row removed.

When I remove that line random images load in the carousel
Yup got that - but if we can't see it is very difficult to diagnose it.

To get to the bottom of this quickly either we need a link to the code or the missing stylesheets, preferably the former because we cannot guarantee the presence of the style sheet will cause the problem to manifest itself.

As I mentioned in my earlier post - your posted code does not appear to demonstrate the problem when that line is removed.
phillystyle123Author Commented:
This has the proload script and the carousel script without

 if(this.complete) {

http://ikonltd.com/artists/preload-test.html
Julian HansenCommented:
Have you noticed with that code everything is getting loaded twice?

$('.row .thumbnail').each(function(i) {

Open in new window


If you look in the code you will see that .thumbnail is declared on two different elements inside each row - so you are going to end up adding the item twice.

This sort of explains what is happening. The .complete was there to check for images. When .each()'ing through the .row .thumbnails you are going to find an <img class="thumbnail"> and an <a class="thumbnail"> for each .row. To avoid adding each thumb twice you use the this.complete which will be true if the element is an image AND the image has finished downloading - effectively filtering out the <a> elements.

Unfortunately, if the image is still in the process of downloading .complete will be false and it will skip the image altogether.

The fix is simple - just add the img to the .thumbnail selector like this
	$('.row img.thumbnail').each(function(i) {
		var item = $('<div class="item"></div>');
		var itemDiv = $(this).parents('div');
		var title = $(this).parent('a').attr("title");
	
		item.attr("title",title);
		$(itemDiv.html()).appendTo(item);
		item.appendTo('.carousel-inner'); 
		if (i==0) { // set first item active
			item.addClass('active');
		}
	});

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
phillystyle123Author Commented:
Oh, yes. This seems to be working!

Any thoughts on getting those captions to load too? Sometimes, after the page first loads, the image will populate the carousel but not the caption.
Julian HansenCommented:
Will have to pick this up a bit later but shouldn't be too difficult.
phillystyle123Author Commented:
thanks julianH -
phillystyle123Author Commented:
Something i noticed related to the caption loading.

After a gallery loads, if you click on the first thumb first, the caption won't load. Clicking on any other thumb, the image and caption load seamlessly. If you click on any other thumb before you click the first thumb, then click the first thumb, the caption for that first thumb will load.
phillystyle123Author Commented:
click on any of these exhibitions to see what i mean:

http://ikonltd.com/past/
Julian HansenCommented:
What is happening is that when you load the modal you don't load the title. This is loaded in the on-slide event handler which is only called when you click one of the slide handles - as soon as you do that the title is populated. So all you need to do is put the loading of the title in the onclick
$('#modalCarousel').on('slid.bs.carousel', function () {
  $('.modal-title').html($(this).find('.active').attr("title")); /* <== THIS .... */
})

/* when clicking a thumbnail */
$('.row .thumbnail').click(function(){
    var idx = $(this).parents('div').index();
  	var id = parseInt(idx);
        $('.modal-title').html($(this).find('.active').attr("title")); /* <== ADDED HERE */
  	$('#myModal').modal('show'); // show the modal
    $('#modalCarousel').carousel(id); // slide carousel to selected
});

Open in new window

phillystyle123Author Commented:
I see what you did. I added the line:

$('.modal-title').html($(this).find('.active').attr("title"));

to the  /* when clicking thumbnail */ section, but I'm still not loading the title/caption when I click the first thumb. I have to click another thumb (which displays perfectly in the modal -caption and image), close that modal, then click on the first thumb again to get the title/caption.
Julian HansenCommented:
The problem is caused by the fact that the .title is loaded when the carousel changes slides but is not initialised when it is created.

The fix I posted uses $(this) which is relative to the carousel - so that won't work but should work with this slight modification
$('#modalCarousel').on('slid.bs.carousel', function () {
  $('.modal-title').html($(this).find('.active').attr("title")); /* <== THIS .... */
})

/* when clicking a thumbnail */
$('.row .thumbnail').click(function(){
    var idx = $(this).parents('div').index();
  	var id = parseInt(idx);
        $('.modal-title').html($('.carousel-inner .active').attr("title")); /* <== CHANGED */
  	$('#myModal').modal('show'); // show the modal
    $('#modalCarousel').carousel(id); // slide carousel to selected
});

Open in new window

What we are saying here is when the thumbnail is clicked get the title attr of the active item of the carousel and set this to the modal title.
phillystyle123Author Commented:
I believe this is working! I added a single quote before .carousel-inner:

$('.modal-title').html($('.carousel-inner .active').attr("title")); /* <== CHANGED */

I will dbl check and mark the question answered. I can't thank you enough for your patience and expertise.

Much appreciated.
Julian HansenCommented:
I have updated the code snippet to correct the error.
phillystyle123Author Commented:
Thanks again for all your help, JulianH! I had just about given up on this - it's hard to believe it's working seamlessly!
Julian HansenCommented:
You are most welcome - good luck with your project.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
jQuery

From novice to tech pro — start learning today.