Simple Effects Plugins

read 33 comments

jQuery has a nice selection of core animation effects, such as .show('speed') and .hide('speed'), .slideUp() and .slideDown(), and .fadeIn() and .fadeOut(). It even has a couple methods for toggling effects — the aptly named .toggle('speed') and .slideToggle().

All of these methods have optional speed, easing, and callback arguments — although a couple are special cases. The .show() and .hide() methods, when used without a speed, will immediately show and hide the matched set of elements with no animation. When the speed argument is included, the matched elements are shown and hidden gradually by animating their height, width, and opacity simultaneously. The .toggle() method shares its name with a method that takes two arguments that alternate being triggered. All of the other effect methods have a default speed of 400ms.

The Flexible .animate()

jQuery internally uses another method, .animate(), to define these shorthand effect methods, and it makes .animate() available to us to do the same. So, let's create our own method that we can use the same way we would use, for example, .slideToggle().

Custom Animation Methods

Someone on the jQuery discussion list recently asked if there was a .fadeToggle() effect in jQuery. In my reply, I admitted that there wasn't one, but suggested that it wouldn't be too hard to create using .animate(). We just attach .fadeToggle to jQuery.fn and pass in the speed, easing, and callback arguments. Then, we return this.animate() with the effect we want, along with those same arguments:

JavaScript:
  1. jQuery.fn.fadeToggle = function(speed, easing, callback) {
  2.   return this.animate({opacity: 'toggle'}, speed, easing, callback);  
  3. };

Now, when we want to use it, we can treat it the same as any other jQuery method. For example:

JavaScript:
  1. $(document).ready(function() {
  2.   $('#fade').click(function() {
  3.     $(this).next().fadeToggle('slow');
  4.   });
  5. });

Try it out:

Watch me fade.

(Incidentally, Dan G. Switzer saw the discussion-list thread and blogged about it himself. Thanks, Dan!)

To create a method that toggles a fade and a slide at the same time, all we need to do is repeat the process, adding a "height" parameter:

JavaScript:
  1. jQuery.fn.slideFadeToggle = function(speed, easing, callback) {
  2.   return this.animate({opacity: 'toggle', height: 'toggle'}, speed, easing, callback);  
  3. };

Give this one a try:

Watch me slide and fade.

Blind Toggle

Let's try one more — a "blind" effect. Instead of changing the height of the element, as we do with a "slide" animation, we're going to move the entire element up and down.

The plugin itself will still be fairly rudimentary, but we'll need to set up some CSS to get it to work correctly. Here is the CSS:

CSS:
  1. #box {
  2.   padding: 10px;
  3.   height: 100px;
  4.   width: 100px;
  5.   background: #e459e9;
  6. }
  7. #box-outer {
  8.   overflow: hidden;
  9.   height: 120px;
  10.   margin: 20px;
  11. }

Notice that we have two "boxes" styled here. The first one will be in the markup itself, but the second one, since it's only being used to help with the effect, will be created by our script. The important properties here are #box-outer's overflow: hidden and height: 120px. The hidden overflow will allow #box to seemingly disappear as it moves up, while the height (which is #box's height plus its top and bottom padding) will keep the rest of the page from shifting along with the box.

Now, on to the plugin code:

JavaScript:
  1. jQuery.fn.blindToggle = function(speed, easing, callback) {
  2.   var h = this.height() + parseInt(this.css('paddingTop')) + parseInt(this.css('paddingBottom'));
  3.   return this.animate({marginTop: parseInt(this.css('marginTop')) < 0 ? 0 : -h}, speed, easing, callback);  
  4. };

While relatively simple, there are a couple things here that might be confusing to jQuery/JavaScript beginners. The first line inside the function declares a variable for the height of this, plus the top and bottom padding ("this" here refers to whatever is matched by the selector in the script that uses the plugin). The parseInt() JavaScript function function looks at a string from left to right until it encounters a non-numeric character. The string of digits up to that character is converted into an integer, stripping off the trailing non-numeric character. So, "10px" becomes 10.

The line that follows animates the marginTop property. It uses a ternary (conditional) operator to test if marginTop is less than zero. If it is, the element's marginTop property animates to 0; if not, it animates to negative the value stored in the h variable.

Finally, we're ready to put this plugin to use:

JavaScript:
  1. $(document).ready(function() {
  2.   var $box = $('#box')
  3.     .wrap('<div id="box-outer"></div>');
  4.   $('#blind').click(function() {
  5.     $box.blindToggle('slow');  
  6.   });    
  7. });

Line 2 "caches" our selector, since we're using it more than once. Then we wrap a div around the "#box" div and bind a click handler to a button. Let's see how this one looks:

Blind me up. Blind me up. Blind me up.

So, now we have three simple effects methods that we apply to our sites for a little extra flair.

Enchant

For really cool effects, check out the brand new jQuery Enchant — a set of effects similar to the popular script.aculo.us effects for Prototype. While Enchant is still only in an Alpha version, it already looks fantastic.

comment feed

33 comments

  1. Oops. Good catch, Braden. Fixed.

  2. John Kitson

    Nice effects - I like the slideFadeToggle since it has a better default behaviour in IE than SlideToggle, which seems to make the contents of the DIV jump a few pixels on completion of the animation. I'm sure that is fixable with CSS but slideFadeToggle just looks slicker. :) Thanks Karl.

  3. Bohdan Ganicky

    Looks like you've confused BLIND and SLIDE. I guess slide stands for moving the entire element and blind stands for just changing the height of an element. Anyway, thanks for this nice howto...things looks so simple now :)

  4. andrea varnier

    thanks Karl, you're great!! :)

  5. D Jones

    I used the fade effect to fade a background image behind some images, but now I cannot make not affect the siblings.

    // do something on document ready
    $(".thumbnailbg").fadeTo("fast", 0.0); // This sets the opacity of the thumbs to fade down to 0% when the page loads
    
    	$(".thumbnailbg").hover(function(){
    		$(this).fadeTo("slow", 1.0); // This should set the opacity to 100% on hover
    	},function(){
       		$(this).fadeTo("slow", 0.0); // This should set the opacity back to 0% on mouseout
    	$(".thumbnail").removeClass("thumbnailbg").show(); // This should make the thumbnail show always
    	});
    });

    Located Here.

  6. Jagan

    Hi,
    i'm working on vista gadgets. wanted to know if JQuery works in sidebar in vista, does it have any restrictions with the same. is it possible to create the same kind of effects in the sidebar gadget...?
    if so can u plz let me how to go about it...?

    Thanks

  7. Hi Jagan,

    Don't know anything about Vista. You might have better luck on the jQuery discussion list.

  8. jQuery is the best!
    I use it everywhere!!!

  9. The only problem is that almost all jQuery components are not so well documented.

  10. Great blog! I've build a tumblr theme with the Slide-Fade effect over here.
    Now I've got the problem that before the .hide removes all content-bodys it is loaded completely. With an slow internet connection it looks not so good. How can I prevent the hidden posts from loafing? I' stumbled over this plugin. But can I use it for my aim?

  11. Some really nice examples, i find that some of the effects in jQuery can be a big lagg-ish on some of the sites i have implimented them in, although on this website they seem to work so smoothly!

  12. Sehr cooler Code, danke
    toni

  13. Florian

    Hi Karl,

    Any idea why this code isn't working anymore when copying the fx.js and fx.slide.js
    from http://www.learningjquery.com/2007/02/more-showing-more-hiding into my template?


    //Checkbox select all/none
    $("#checkboxes_all").toggle(
    function() {
    $('input[@type=checkbox]').attr('checked', 'checked');
    },
    function() {
    $('input[@type=checkbox]').removeAttr('checked');
    });

    As soon as I put both snippets into it I can click and nothing happens :-/

    thanks
    Florian

  14. Hi Florian,
    Not sure which fx.js and fx.slide.js files you're referring to. They aren't listed anywhere on the page you link to above.

    If you're using jQuery 1.2 or higher, you should omit the "@" symbol in the selector. Actually, jQuery has a special ":checkbox" selector, so you could use $('input:checkbox') Also, try using .attr('checked', true) instead of .attr('checked', 'checked').

    Hope that helps.

  15. is there a vertical .blindToggle ?

  16. Dan

    How would I make it toggle to say 50% opacity and than toggle back to 100%?

  17. Hi Dan,
    Try something like this:

    jQuery.fn.fadeSomeToggle = function(speed, easing, callback) {
      var op = $(this).css('opacity');
      return this.animate({opacity: op != 0.5 ? 0.5 : 1.0}, speed, easing, callback);
    };

    That should do it.

  18. pablo

    Could I use this events of jQuery to slide panels from right to left?

  19. Jquery is the best!! I use it on my face…

  20. I am a jQuery plugin developer and I never knew that using 'toggle' inside animate is possible. Thanks for this great tip.

  21. Jquery is very gr8. Its very useful for development with static as well as dynamic pages.

  22. Josh

    Love this tutorial. One question on the blind toggle, how can you make the panel start out hidden at the top?

  23. Hey Bradon, nice tutorial, but i cannot manage to make it start HIDDEN first tan toggle out and in. Like Josh said.

  24. George

    Presumably to make something start hidden you could call

    $('#blind').hide();

    first of all within the $(document).ready(...);

    That way it will be visible for users without javascript.

    GC

  25. Peter

    Is is possible to have something slideUp and FadeOut at the same time? Can effects be chained in this manner?

  26. Hi Peter,

    Look at the slide-fade toggle example. That one slides an element and fades it at the same time. And yes, effects can be chained.

  27. I'm fairly new to jQuery, but I've been using several of the effects repeatedly. Now I'm stuck with an effect that I really need, but cannot seem to find a way to make it work in jQuery.

    Basically all that I want is a Blind Toggle effect turned upside down. I want the element to slide down out of view and then slide back up into view. It sounds simple enough considering all of the things you can do with jQuery, but I just can't find a way to accomplish this.

    The two effects slideUP (hides) and slideDown (reveals) work in the exact opposite manner that I'm needing, otherwise I would just use that. Any ideas?

  28. Is there a way to get this Fade effect and or slide effect in jQuery on a mouseover event and can you either tell me or help me on how to implement this. Please email me with the solution. Don't know when I can get back to the blog.

  29. Rohit

    Hello Karl,
    Thanks for such a nice example.I have one problem i have one table with rows containing select box in each and having name "mytable".when i use fadeToggle() ,i just don't want any value from select box of mytable
    how i can manage this.Will you suggest me the way

3 Pings

  1. [...] Simple Effects Plugins- Nice animation effects that can easily toggle, hide, show, fade, slide [...]

  2. [...] Simple Effects Plugins- Nice animation effects that can easily toggle, hide, show, fade, slide [...]

  3. [...] Simple Effects Plugins- Nice animation effects that can easily toggle, hide, show, fade, slide [...]

Leave a Comment

IMPORTANT:

  • If you wish to post code examples, please wrap them in <code> tags.
  • Multi-line code should be wrapped in <pre><code> </code></pre>
  • Use &lt; instead of < and &gt; instead of > in the examples themselves. Otherwise, you could lose part of the comment when it's submitted.