Treehouse: Grow your CSS skills. Land your dream job.

#79: Complete/Non-Queuing Animations with jQuery

When you use jQuery's .animate() function with something like a hover event, those animations will "queue up". That is, if you hover multiple times, that animation will fire multiple times. The classic method to prevent this is to throw in a .stop() before the animation, but I find this abrupt and not ideal, because it prevents the animation from completing a full cycle. In this screencast we'll look at a few attempts at solving this and ultimately using a plugin that does a great job.

Links from Video:

Comments

  1. Benjamin Mayo
    Permalink to comment#

    Haven’t watched the video yet (will do soon) but can you please make the screencasts more prominent on the homepage if they’re new?

    I have to scroll every time I visit css-tricks.com just to see if there is a new screencast. I would much prefer the screencast to replace the latest article if it is more recent.

    • Michele
      Permalink to comment#

      It appears at the top for me…

    • Eddy
      Permalink to comment#

      Me too, and if you only want screencasts, bookmark this page:

      http://css-tricks.com/new-screencast/

      Also, there’s RSS :)

    • Benjamin Mayo
      Permalink to comment#

      Unless I’ve been a complete idiot, Chris has just added that. I’m certain it never used to be like that.

    • Kyle Cotter
      Permalink to comment#

      No, you aren’t an idiot…Chris writes an article to correlate to the screencast. Its just when you found the screencast, he hadn’t written the article to link to it yet. I saw the same thing you did, video at bottom, but no article YET…he did post an article up with relation to this video, and hence now you can see it at the top of the page. :D

    • Benjamin Mayo
      Permalink to comment#

      Thanks for proving my sanity.

  2. Kyle Cotter
    Permalink to comment#

    Great video as always. Actually need to implement something similar to this on a client site, will definitely be using this plugin. Thanks again!

  3. Josh
    Permalink to comment#

    Works great, but is there a way to do the same thing for the opacity?

    • Ralf Stoltze
      Permalink to comment#

      You can use hoverFlow() as you would use animate(). So, yes, you can also animate the opacity!

    • Sebastiaan Stok
      Permalink to comment#

      The next parameter is passed to animate() :)

      Type is required because the function needs to know what action taking place.

      Only allow hover events
      Either: ‘mouseover’, ‘mouseenter’, ‘mouseout’, ‘mouseleave’

      Yes, I know JavaScript ;)

      Great plug-in.

  4. Jack
    Permalink to comment#

    Hey Chris, great screencast!

    The animate property in jQuery has long been a really buggy tool, but this solution works great!

    Keep up the good work (please :P).

    Also, can you do a screencast on preventing mySql injections? I keep getting a load of spam in the comments of my first blog post – I think it has something to do with mySql…

  5. alan
    Permalink to comment#

    Great video Chris.

  6. Scott block
    Permalink to comment#

    Great screencast Chris.
    I agree, why isn’t this in jQuery core??
    Mad props to Ralf Stoltze!
    I’m off to go fix my glitchy multiple hovers now.

  7. Ginger
    Permalink to comment#

    @Chris: This screencast isn’t in the Screencast section at http://css-tricks.com/video-screencasts/ !!

  8. TeMc
    Permalink to comment#

    Nice vid Chris !

    Very satisfying to hear you being satisfied xD

    I share your happiness though, it is indeed a great thing and I’ll definitly will be using this plugin from now on. It takes like 10 more characters and fixes pretty much every possible (minor) bug there is with animations.


    Temc

  9. Wyverald
    Permalink to comment#

    You’re so cute. And thanks, of course =]

  10. Ryan
    Permalink to comment#

    Wait, instead of using that plugin or .stop(), why don’t you just use queue: false in the jQuery JSON object for the 2nd argument of .animate() ?

    Am I missing something that makes my solution invalid, or did you not know about this option?

    • Chris Coyier
      Permalink to comment#

      If you check out the linked article above, and see those demos, using the queue: false; basically behaves the exact same way as .stop() does.

  11. Eddy
    Permalink to comment#

    @Chris – there is something wrong with the downloadable version, it’s really bright. The first three divs aren’t even distinguishable from the background. The only version is fine, so it can’t be my screen.

  12. Joël Cox
    Permalink to comment#

    Cool pointer Chris. Hopefully this WILL be added to the jQuery core. One question though, about when you refer to those multiple classes.

    Why would you use those element specific identifiers like topbox-one as classes instead of id’s in this example? Unless you were planning on using these elements multiple times for e.g. with/without plugin demo page.

    Thanks!

    • Chris Coyier
      Permalink to comment#

      They might as well have been ID’s in this example, but it really doesn’t matter much. It was just easier to write, demonstrated that ability of HTML, and would allow for future duplicates of that nav.

  13. Jacob
    Permalink to comment#

    Chris, awesome screencast, as usual!

    I can’t find any documentation regarding .click() with hoverFlow… Basically, I’m using the same exact syntax as I would with a .hover(), but am not getting the desired result… in fact, nothing happens at all.

    Can I use other actions besides .hover() and .live()? Or do I need to use the .bind() method to bind a click event to the selector?

    Cheers,
    Jacob

    • Ralf Stoltze
      Permalink to comment#

      Hi Jacob,

      hoverFlow is currently limited to hover events (mouseover, mouseenter, mouseout, mouseleave). To be honest, I have a hard time finding a valid use case for a click event that queues up. Could you give an example?

    • LuK
      Permalink to comment#

      =)…I could…also have this problem (and also using hoverFlow for hover-stuff) with the click…

      I have a button on the Front-Page which opens a Form, if somebody stupid clicks and clicks and clicks the animation will build up a queue and it will go on and on but I thought if you click so many times you’re an idiot yourself so it’s not my problem…but if there was a solution I would be happy to implement it =)!

  14. Eamonn
    Permalink to comment#

    Dude, that was inadvertently the funniest screencast!

    “I’ve got somewhere else to be…

    “ooooh, see how smooth that is? oooooh just silky smooth, ooooh…

    “copy and..no…copy…it won’t paste!

    “if I don’t think it’s crap, I’ll talk about it here for money….

    “OK, I’m outta here!”

    Top stuff man, keep it up! :)

  15. Vibhor
    Permalink to comment#

    I am not impressed easily…but i must say its good

  16. Steven Davis
    Permalink to comment#

    You could do all that, or you could just use the hoverIntent plugin, which is an awesome replacement for the deftaul hover behavior. It’s like a SMART hover :)

  17. Alan
    Permalink to comment#

    Chris, have you considered late night? I hear there’s an opening.
    Hilarious screencast. Thanks!

  18. Liam Goodacre
    Permalink to comment#

    Hey I just figured it out…
    ThankYouAndGoodNight ;) x

    JSCode:

    // on ready
    $(function() {
    // setup
    $('.box').hover(function() {
    $e = $(this); // this cache
    // dequeue, stop, then animate height
    $e.dequeue().stop().animate({
    height: '200px'
    });
    }, function() {
    $e = $(this); // this cache
    $e.animate({ // animate height
    height: '50px'
    });
    });
    });

    Html:
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>

    CSS:

    .box {
    width: 100px;
    float: left;
    display: inline;
    height: 50px;
    background-color: #888;
    margin-right: 10px;
    }

  19. Egon Elbre
    Permalink to comment#

    Here’s what I thought of:


    $(function() {
    $(".topbox").hover(
    function(){
    $(this).stop(true, false).animate({ height: "100px" });
    },
    function(){
    $(this).animate({ height: "20px" });
    });
    });

    The point is that actually you want to queue the animation going back, but when the mouse hovers you want to clear the queue and start over.

  20. Jelmer de Maat
    Permalink to comment#

    Chris, this was the funniest screencast yet. Especially the end. :D

    Thanks!

  21. ariful
    Permalink to comment#

    hi Chris,

    thanks for your nice screen casts and free downloads.

    will you please makes a screen cast on Feed and feedburner for us.

  22. Ben
    Permalink to comment#

    Thanks Chris! I’m looking forward to using it!

  23. Daniel
    Permalink to comment#

    hey chris, and other people,
    im new to javascript and jquery, and i needsome help.

    i have this script, exactly like the one from the screencast, but mine dont work
    $(function() {

    $(".box").hover(function(){

    $el = $(this);

    $el.stop().animate({
    height: "100px"
    });

    }, function() {

    $el = $(this);

    $el.stop().animate({
    height: "50px"
    });

    });

    });

    i dont know whats wrong with it.

  24. Brad
    Permalink to comment#

    Does anyone know how to link together multiple animations, and have it still be smooth with hoverFlow?

    For example, on hover, a link moves down 5 pixels, then quickly up 2 pixels, then back down 2. Sort of a “bounce” effect animation. I’ve accomplished this before, but it had the “queue up” problem.

    Thanks,
    Great video Chris,
    Brad

    • Adrian
      Permalink to comment#

      just look into the source and try to figure out what it does! all that hoverflow does is dequeue the animation and then restart it! just write your own code that does essentially the same thing and you can easily link the animations

  25. Adam
    Permalink to comment#

    Hey Chris,
    Thank you for posting this screencast. I wanted to take this tutorial a step further but I am running into some problems. I was wondering if you could help me out.

    Like in your example, I want to have the div animate on the hover but in my example, I want to make it so, on click, a hidden div pops up (toggle). I tried using multiple classes but for some reason, when you click, all the divs show, instead of just one I clicked on. I was wondering if you could offer me some assistance? Any help would be amazing.
    -Adam

    • Liam Goodacre
      Permalink to comment#

      Hi Adam,
      In your click event, you refer to $(‘.box’);
      this identifies all the .box elements, not just the one relating to the current $(“.click”),
      to refer to only the relevant “.box”, use this instead:
      $(‘.box’, this)

      This will find any “.box”, within ‘this’.

      Hope this helps,
      Regards, Liam

    • Adam
      Permalink to comment#

      Thanks Liam!

  26. Anton
    Permalink to comment#

    Defiantly something I was going to look for eventually, nice to run into it by accident.

  27. Nightshade427
    Permalink to comment#

    In the episode you are using jquery 1.4, I think clearQueue would work to fix the queuing problem.

  28. George Katsanos
    Permalink to comment#

    Funny screencast, thanks Chris and ‘course thanks Ralf Stoltze for the plugin. Respect.

Leave a Comment

Posting Code

We highly encourage you to post problematic HTML/CSS/JavaScript over on CodePen and include the link in your post. It's much easier to see, understand, and help with when you do that.

Markdown is supported, so you can write inline code like `<div>this</div>` or multiline blocks of code in in triple backtick fences like this:

```
<script>
  function example() {
    element.innerHTML = "<div>code</div>";
  }
</script>
```