Hide jCarousel Until It Loads

Polishing the user interface is far to often categorized as "if you have time" which, from my experience is almost, always never. I am just as guilty, putting it off until crunch time. My own site is on a whole other level of "if you have time" as I am not making money from this, and quite often I am using it as a sandbox (slowly getting away from this, I'm finally using GitHub!) Today, I decided to fix the featured carousel on my homepage.

This site, built on Drupal 7, is using Views and the jQuery jCarousel plug-in to render the carousel on the homepage, and hopefully soon, the image thumbnails on my blogs. It works well, except that as the page loads, you quite often see all the images, that are supposed to be hidden, loading on top of each other as in the lead image. A nice way of rendering this would be to hide the carousel until at least the first image has loaded.

We will pretend that you know how to do this and move ahead to the problem I faced with jCarousel + Views + Drupal: when you expose the carousel, after it initially had a display: none; inline style, the first image is loaded and works, but all subsequent images are either not loaded or are only partially showing. To make this bug even more annoying, if you clicked the arrow to go in the opposite direction, the images worked! I started hunting around the internet to see if anyone else had similiar issues when I can across this post on StackOverflow.com. The suggestion to put the carousel out-of-site to load, and then move it back had not occurred to me.

My code ended up looking like this:

jCarousel View tpl

<?php
/**
* @file jcarousel-view.tpl.php
* View template to display a list as a carousel.
*/
?>

<div id="loading"><img src="path/to/images/loading.gif" alt="loading" /></div>
<ul class="ul <?php print $jcarousel_classes; ?>" style="position: absolute; left: -9999em;">
  <?php foreach ($rows as $id => $row): ?>
    <li class="<?php print $row_classes[$id]; ?>"><?php print $row; ?></li>
  <?php endforeach; ?>
</ul>

Theme Layer Javascript

(function ($) {
  Drupal.behaviors.theme = {
    attach: function() {
      // jcarousel shenanigans
      $("#loading").hide();
      // hide the out-of-site carousel and then position it so we can fade in
      $(".jcarousel-clip ul").hide().css({"position":"relative","left":"inherit"}).fadeIn(1500);
    }
  };
})(jQuery);

Two very simple lines of jQuery, and bravo! Letting it render before hiding it and applying effects works as desires, and *now* user's will be greeted by a loading GIF and a carousel that fades in smoothly.

Of note, I had originally planned on using the jQuery .load() function, but this does not work well on images. There is a known bug with multiple browsers running into trouble with cached images. There is a jQuery script that gets around this, but it is currently in a broken state according to the author.

RSS

Subscribe to my blog feeds:

All Tech Life Photos Food

Looking for a good way to consume RSS feeds?
Google Reader + Reeder for Mac

Contact

Did you just find a glaring error in this blog? Comments are not enabled yet, so please use the Contact Form to let me know about it.