21

I was hoping this jQuery plug-in would work, but it didn't:

http://andowebsit.es/blog/noteslog.com/post/how-to-fix-the-resize-event-in-ie (old link was noteslog.com/post/how-to-fix-the-resize-event-in-ie ).

I added a comment to his site, but they're moderated, so you might not see it yet.

But anyhow, let me explain my desire. I want a "resize" type of event to be fired when the user either pauses his resize, and/or completes his resize, not while the user is actively dragging the browser's window resize handle. I have a fairly complex and time consuming OnResizeHandled function I need to run, but not run 100 times just because the user widened the window by 100px and the event was fired for ever pixel of movement. I guess a best bet would be to handle it once the user has completed the resize.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
DMCS
  • 31,720
  • 14
  • 71
  • 104

7 Answers7

76

How about some code like this:

function resizeStuff() {
 //Time consuming resize stuff here
}
var TO = false;
$(window).resize(function(){
 if(TO !== false)
    clearTimeout(TO);
 TO = setTimeout(resizeStuff, 200); //200 is time in miliseconds
});

That should make sure the function only resizes when the user stops resizing.

Pim Jager
  • 31,965
  • 17
  • 72
  • 98
  • 1
    Sorry but I don't understand how this works... how does TO initially become not false? I see it's false, and then the only way it becomes not false is after it is already not false. – TetraDev Mar 25 '16 at 20:06
  • 2
    Edit: Nevermind, I thought TO = setTimout was a part of the if. Bad practice to not use curly braces - makes the code harder to read quickly. Just just braces, dude. – TetraDev Mar 25 '16 at 20:25
9

Borrow some ideas from concurrency solutions to manage the flood of events coming from the browser.

For example, when you first get a resize event, set a flag to true indicating that the user is currently resizing. Set a timeout to call the actual resize event handler after 1 second. Then, whenever this flag is true, ignore the resize event. Then, in the actual handler, once everything is done and correct, set the flag back to false.

That way you only process the latest event once every second (or some other period of time depending on your requirements). If the user pauses in the middle of resizing, it will process. If the user finished, it will process.

This might not be suitable for you, but there are many other ways of using locks that might be more helpful.

Welbog
  • 59,154
  • 9
  • 110
  • 123
  • That's what the jQuery plugin does, but it fails to do it correctly. – DMCS Mar 20 '09 at 19:31
  • I don't have enough knowledge to do it correctly myself. Hence why I'm asking for the knowledge here. :) BTW, I'm not after width, height, top, left. I'm after knowing when the resize event is complete (meaning the user let go of the browser's resize handle) – DMCS Mar 20 '09 at 20:06
  • Well, this kind of thing is really easy to do, so don't get discouraged. Go here: http://www.w3schools.com/htmldom/met_win_settimeout.asp It will get you started on the SetTimeout function, which is really all you need in this situation. When you get a resize event, don't process it directly... – Welbog Mar 20 '09 at 20:44
  • (continued) ... only process the event after a certain period of time has elapsed. That way you don't process the event too often. – Welbog Mar 20 '09 at 20:45
  • @TetraDev: Were my goal were to merely provide answers, I would; however, my goal is to educate. – Welbog Mar 28 '16 at 13:35
5

Paul Irish has a great Debounced jQuery plugin that solves this problem.

James
  • 1,391
  • 2
  • 14
  • 20
  • That's what I ending up coding for my solution not too long after I posted the original question, I had added a timer that ensured an event update would only go out x number of milliseconds. – DMCS Jul 15 '11 at 18:37
  • @DMCS if that's what you ended up doing wouldn't that make this the right answer? :) – James May 02 '12 at 15:29
  • 1
    Based upon the answer I received on March 20, 2011 from Welbog, I coded my own. On April 9th,2011 I accepted their answer. You then, after I've already accepted their answer, answered June 16 2011. I did not use Paul's plugin, I wrote my own somewhere between March 20 and April 9th of 2011. You got two upvotes for your late answer, which is equivalent in points to an accepted answer. – DMCS May 02 '12 at 19:06
  • @DMCS ahh well...worth a shot :) – James Jun 25 '12 at 19:10
2

If you are into libraries, you should checkout underscore, underscore already handles your need and many more you will probably have in your projects.

here is an example of how underscore debouncer works:

// declare Listener function
var debouncerListener = _.debounce( function(e) {

    // all the actions you need to happen when this event fires

}, 300 ); // the amount of milliseconds that you want to wait before this function is called again

then just call that debouncer function on the resize of the window

window.addEventListener("resize", debouncerListener, false);

checkout all the underscore functions available here http://underscorejs.org/

JrBriones
  • 2,930
  • 1
  • 13
  • 5
1

How about setting a timeout for when the user pauses the resize? Reset the timeout when resizing occurs, or fire the resize event handler if the timeout expires.

Russ Cam
  • 124,184
  • 33
  • 204
  • 266
  • How do you know when the user pauses the resize? What is the exact syntax in javascript/jQuery to get this info that the user has paused? – DMCS Mar 20 '09 at 19:34
  • You know when the resize is "paused" when the width and the height of the element have not changed for a specified period i.e. the span of the timeout you set. – Russ Cam Mar 20 '09 at 20:57
0

I extended some days ago the default jQuery on-event-handler. It attach an event handler function for one or more events to the selected elements if the event was not triggered for a given interval. This is useful if you want to fire a callback only after a delay, like the resize event, or else. https://github.com/yckart/jquery.unevent.js

;(function ($) {
    var methods = { on: $.fn.on, bind: $.fn.bind };
    $.each(methods, function(k){
        $.fn[k] = function () {
            var args = [].slice.call(arguments),
                delay = args.pop(),
                fn = args.pop(),
                timer;

            args.push(function () {
                var self = this,
                    arg = arguments;
                clearTimeout(timer);
                timer = setTimeout(function(){
                    fn.apply(self, [].slice.call(arg));
                }, delay);
            });

            return methods[k].apply(this, isNaN(delay) ? arguments : args);
        };
    });
}(jQuery));

Use it like any other on or bind-event handler, except that you can pass an extra parameter as a last:

$(window).on('resize', function(e) {
    console.log(e.type + '-event was 200ms not triggered');
}, 200);

http://jsfiddle.net/ARTsinn/EqqHx/

yckart
  • 32,460
  • 9
  • 122
  • 129
0

Since it's built in jQuery, can't you bind some kind of onComplete event to the extension and pass a function that should be executed when it's called?

Edit:

When the user starts resizing the window, set an interval that watches the window's dimensions. If the dimensions haven't changed in a pre-set time period of your specification, then you can consider the window resizing "completed". Your javascript function of choice in this would be setInterval(), which accepts two arguments - a function to call each tick, and how long each tick takes in milliseconds.

As to how to write that specifically within the jquery framework, well, I don't know enough about jquery to be able to tell you that. Perhaps someone else can help you more specifically, but at the same time you may consider extending the jquery extension you already linked with an onComplete event that works like I just described.

Rahul
  • 12,181
  • 5
  • 43
  • 64
  • An onComplete event would be very nice. However, what is the javascript (or jQuery) syntax/command for this? – DMCS Mar 20 '09 at 19:33
  • I don't know enough about jquery to provide you with a specific answer, but Russ Cam suggests approximately the same thing in his solution. I'll explain in an edit. – Rahul Mar 21 '09 at 00:51