Home > jquery > Debounced resize() jQuery plugin

Debounced resize() jQuery plugin

August 11th, 2009

If you've ever attached an event handler to the window's resize event, you have probably noticed that while Firefox fires the event slow and sensibly, IE and Webkit go totally spastic.

PPK lays it out like this:

  • In IE, Safari, and Chrome many resize events fire as long as the user continues resizing the window.
  • Opera uses as many resize events, but fires them all at the end of the resizing.
  • Firefox fires one resize event at the end of the resizing.

When I first saw John Hann's debounce post, this use case is what I immediately thought of.

This isn't exactly throttling, but it's close. Basically debouncing will fire your function after a threshold of time (e.g. 100ms) has elapsed since the last time it's tried to fire. Throttling would withhold subsequent firings, but debouncing waits for the last one and runs that.

Take a look at the difference on the demo.

The code for smartresize:

(function($,sr){
 
  // debouncing function from John Hann
  // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
  var debounce = function (func, threshold, execAsap) {
      var timeout;
 
      return function debounced () {
          var obj = this, args = arguments;
          function delayed () {
              if (!execAsap)
                  func.apply(obj, args);
              timeout = null; 
          };
 
          if (timeout)
              clearTimeout(timeout);
          else if (execAsap)
              func.apply(obj, args);
 
          timeout = setTimeout(delayed, threshold || 100); 
      };
  }
	// smartresize 
	jQuery.fn[sr] = function(fn){  return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };
 
})(jQuery,'smartresize');
 
 
// usage:
$(window).smartresize(function(){  
  // code that takes it easy...
});

Pretty straightforward stuff. What else do you think would be an appropriate use of debounce()?

jquery

  1. August 12th, 2009 at 08:53 #1

    For generalized jQuery-friendly debouncing and polling, interval, and timeout handling, you might want to check out my doTimeout plugin, as it does all this and quite a bit more (with a slightly larger footprint, of course)!

    - Ben

  2. August 21st, 2009 at 22:17 #2

    Hey Paul!

    Glad you found a great use for debounce(). Interestingly, I find I typically wish for Firefox to fire the resize event more often! (For those few times when I can't quite get a 100% liquid layout with CSS.)

    Side note for readers: Set the debounce function's execAsap parameter to true and the event will fire at the beginning of the timeout period, like throttling.

    @Ben: your doTimeout plugin is pretty cool. It's unbelievably well documented, too. Kudos!

  3. September 12th, 2009 at 22:48 #3
  4. September 13th, 2009 at 08:35 #4

    @Brandon Aaron Very nice work Brandon. This is solid.

  5. November 27th, 2009 at 11:30 #5

    I just wrote a special event to debounce the resize event. I kept your name "smartresize".
    http://github.com/lrbabe/jquery-smartresize/

  6. January 3rd, 2010 at 21:17 #6

    Excellent stuff. It's quite confusing right at first when your browser starts firing waaay too many events. Many thanks for the straightforward tipoff for how to get it working more reasonably.

  7. January 19th, 2010 at 06:38 #7

    I've just changed the bind to scroll and got it working on the scroll event! Thanks

  8. January 27th, 2010 at 15:44 #8

    Hi Paul,

    This looks like a perfect solution to a problem I'm having. I'd love to use this in a GPL WordPress plugin. Since there doesn't appear to be a code license statement on the blog – can you confirm if this is OK? Feel free to drop me an email if you need any further information.

    Thanks
    Lee

  9. Tommy
    February 3rd, 2010 at 10:56 #9

    Hi Paul,

    Thank you very much, I have been looking for this for a while.

    Tommy

  10. December 2nd, 2010 at 21:57 #10

    The example you link to has a default threshold of 100. I've tested this on Safari 5.0.2 and that is too short a time. In that browser the event fires almost as often as it does without a debounce. I found increasing this to 500, however, avoids the issue. Hope this helps someone running into Safari issues using this code. Thanks for the code!

  11. Ram
    January 10th, 2011 at 08:08 #11

    I used this script in IE8 with threshold of 500/1000. it slows down the process of calling the handler. However how to 'end' this event after the first execution?

  12. April 13th, 2011 at 04:06 #12

    @Louis-Rémi Babé
    The new address of my smartresize special event is here:
    http://github.com/louisremi/jquery-smartresize/

  1. January 14th, 2010 at 21:07 | #1
  2. March 30th, 2011 at 02:39 | #2
  3. May 12th, 2011 at 00:09 | #3
  4. May 20th, 2012 at 23:57 | #4

For code blocks, use <pre lang="javascript">. css and html4strict are also accepted.