Simple jQuery slideshow bubble messages

Tuesday, March 23rd 2010 at 4:09am

Yesterday our start-up was presenting at DEMO conference (Spring 2010) and I refactored the presentational page, to be more subtle, clean and more up to the point about what we’re doing.

I needed to make pairs of balloons display sequentially, with some simple animation of opacity. As a bonus, I added that the yellow connection shines between displays of the two balloons.

I was googling around for slideshow implementations in jQuery, but most of them are heavyweight and do too much. Then I stumbled upon this nice little article, from which i drew my inspiration.

The result can be seen on http://mmatcher.com and looks like this:

I mostly used Rails’ default — Prototype, but a series of coincidences lead me to use jQuery for the first time. I found it to be quite a bit different, and I needed to wrap my head around the “chain everything” rule. In the end it’s API documentation is very good, so I was quickly making progress.

So the markup is structured as a series of DIVs, each with a class match. I also use the class name of active, to denote which bubbles should be displayed at any given moment.


<div id='examples'>
  <div id="match1" class="match active">
    <div class='user1'>
      <h4>User 1</h4>
      I need a babysitter for tonight...
    </div>
    <div class='user2'>
      <h4>User 2</h4>
      I am an experienced babysitter and children love me.
    </div>
  </div>
  <div id="match2" class="match">
    <div class='user1'>
      <h4>User 1</h4>
      Anyone for a tennis match today?
    </div>
    <div class='user2'>
      <h4>User 2</h4>
      I'd love to play some tennis in the afternoon.
    </div>
  </div>
  <div id="match3" class="match">
    <div class='user1'>
      <h4>User 1</h4>
      I am a math tutor, need help?
    </div>
    <div class='user2'>
      <h4>User 2</h4>
      I've got problems with math in school, need assistance.
    </div>
  </div>
  <div id="match4" class="match">
    <div class='user1'>
      <h4>User 1</h4>
      Urgently need a plumber!!!
    </div>
    <div class='user2'>
      <h4>User 2</h4>
      Broken pipes, leakages? I am Plumber Ben, how can I help you?
    </div>
  </div>
  <div id="match5" class="match">
    <div class='user1'>
      <h4>User 1</h4>
      Selling old laptop for $500.
    </div>
    <div class='user2'>
      <h4>User 2</h4>
      Looking to buy a nice cheap laptop computer for school.
    </div>
  </div>
</div>

By default, we set that the examples are not displayed in the CSS.


#examples {
  font: normal 16px/20px Helvetica, sans-serif; }
  #examples .match .user1, #examples .match .user2 {
    position: absolute;
    display: none;
  }

Now to the slideshow…

We simplify things, by setting the first match’s class to active, directly in the HTML. We use that, to always get the element we want to display via JavaScript. After we get the current element (the one that’s showed and animated), we try to find the next sibling, with jQuery’s next() method and attach to it the class active. This way, when the function is called again, it operates on the next element.

The function is called recursively and with a timeout.


function balloon_switch() {
  /* Get currently active element (has active class). */
  var $match = $("#examples .active").first();
  /* Animate it. */
  match_animate($match);
  /* Remove active class from it. */
  $match.removeClass('active');
  /* Find next sibling. */
  var $next = $match.next();
  /* If next sibling doesn't exist, e.g. we're at the last element, set next to first. */
  if ($next.length == 0) $next = $("#examples").children().first();
  /* Add active class to next element. */
  $next.addClass('active');
  /* Call self again after 7s. */
  setTimeout("balloon_switch()", 7000);
}

This function calls match_animate() on each active element. The animate function just sets up a couple of delays and jQuery animations of opacity, to smoothly transition in bubble 1 first, then pulsate the yellow m and finally display the second bubble.


function match_animate(match) {
  /* Show the match container (hidden by default) and set it to hide after 6s. */
  match.show().delay(6000).animate({opacity: 'hide'}, 'slow');
  /* First bubble appears after half a second and hides after. */
  match.children(".user1").delay(500).animate({opacity: 'show'}, 'slow').delay(5500).hide();
  /* Pulsate the yellow m after the first bubble has been around for 1s. */
  setTimeout("pulsate_match()", 1500);
  /* Show and hide the second bubble accordingly. */
  match.children(".user2").delay(3000).animate({opacity: 'show'}, 'slow').delay(3000).hide();
}

The code that make the yellow m shine could probably be optimised somehow, but I think for this simple example it’s doing the job just fine.

It uses the handy jQuery delay() function that makes it easy to chain delayed animations, one after another.


function pulsate_match() {
  $("#mmatch").animate({opacity: 'show'}, 150).delay(150).animate({opacity: 'hide'}, 150).delay(150)
  .animate({opacity: 'show'}, 150).delay(150).animate({opacity: 'hide'}, 150);
}

We hook everything up by calling our functions when the page finished loading. We create the pulsating-m’s div via JavaScript, since it has no semantic meaning to deserve being in the actual markup.


$(document).ready(function(){
  mmatch = $("<div id='mmatch'></div>").appendTo("body");
  setTimeout("balloon_switch()", 1500);
});

And that’s it! I think the code is simple and self-explanatory, if you have any questions, please post them in the comments.

The code is far from being the most optimised, since I have a lot of JavaScript studying ahead of me, but it’s simple and it works well.

If you know of a better way of doing something, I’ll be thrilled to see it, and don’t forget to check out mmatcher and to follow us on twitter here

If you've enjoyed this, you should follow me on Twitter.
To read more, head over to break the bit.