Approximating resizeComplete in jQuery
Most browsers fire resize events continuously as the viewport is scaled. This is handy when your interface needs to change responsively during a resize, but a PITA if you only need to perform a single action when it’s “done.” Even worse is when that action is resource-intensive (such as an animation), as it can render your resize choppy or unbearable. I was faced with this very problem on a recent site design, and I thought I’d share the solution I arrived at.
The basic idea is to call a function within the resize() callback on a delay. This function checks to see if the width and height of the window have maintained dimensions during this period, and if so performs your resize completed action. Here is the code in jQuery:
- // global queue of setTimeout handles
- var handleQueue = new Array();
- $(window).resize(function() {
- // store current dimensions using .data()
- $(window).data(′oldW′, $(window).width()).data(′oldH′, $(window).height());
- // call our function on a delay and push its handle on the queue
- handleQueue.push(setTimeout(_completeCheck, 750));
- });
- function _completeCheck() {
- var $window = $(window);
- if ($window.width() == $window.data(′oldW′) && $window.height() == $window.data(′oldH′) {
- // *** DO YOUR RESIZE COMPLETE STUFF HERE ***
- // unwind setTimeout handle queue to prevent further execution
- while (handleQueue.length != 0)
- clearTimeout(handleQueue.shift());
- } else {
- // otherwise shift the first handle off since it already executed
- handleQueue.shift()
- }
- }
I chose to go the route of a handle queue because I feel it’s a lot cleaner than some global boolean. The boolean approach will still execute delayed function calls after the resize is “done,” and I’d rather unwind a queue and cancel those calls immediately since they’re unnecessary. You might also need to noodle with the setTimeout interval to achieve the responsiveness you’re after. In my case, 750ms was just right.