jQuery 拖动调整大小手柄时多次触发javascript调整大小事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/667426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 09:32:56  来源:igfitidea点击:

javascript resize event firing multiple times while dragging the resize handle

jqueryjavascript-eventswindowresize

提问by DMCS

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

我希望这个 jQuery 插件可以工作,但它没有:

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 ).

http://andowebsit.es/blog/noteslog.com/post/how-to-fix-the-resize-event-in-ie(旧链接是noteslog.com/post/how-to-fix-the-resize -事件在即)。

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 whilethe 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.

但无论如何,让我解释一下我的愿望。我希望在用户暂停调整大小和/或完成调整大小时触发“调整大小”类型的事件,而不是用户主动拖动浏览器的窗口调整大小句柄时触发。我有一个相当复杂且耗时的 OnResizeHandled 函数,我需要运行,但不能运行 100 次,因为用户将窗口扩大了 100 像素,并且该事件被触发了移动像素。我想最好的办法是在用户完成调整大小后处理它。

采纳答案by Welbog

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.

例如,当您第一次收到 resize 事件时,将标志设置为 true 表示用户当前正在调整大小。设置超时以在 1 秒后调用实际的调整大小事件处理程序。然后,只要此标志为真,就忽略调整大小事件。然后,在实际的处理程序中,一旦一切都完成并正确,将标志设置回 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.

这可能不适合您,但还有许多其他使用锁的方法可能更有帮助。

回答by Pim Jager

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.

这应该确保函数仅在用户停止调整大小时调整大小。

回答by James

Paul Irish has a great Debounced jQuery pluginthat solves this problem.

Paul Irish 有一个很棒的Debounced jQuery 插件可以解决这个问题。

回答by JrBriones

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

然后只需在调整窗口大小时调用该 debouncer 函数

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

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

http://underscorejs.org/查看所有可用的下划线函数

回答by Russ Cam

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.

如何设置用户暂停调整大小的超时时间?发生调整大小时重置超时,或者在超时到期时触发调整大小事件处理程序。

回答by Rahul

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?

既然它是用 jQuery 构建的,你不能将某种 onComplete 事件绑定到扩展并传递一个应该在调用时执行的函数吗?

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.

当用户开始调整窗口大小时,设置一个观察窗口尺寸的间隔。如果尺寸在您规范的预设时间段内没有改变,那么您可以考虑“完成”窗口大小调整。您选择的 javascript 函数将是 setInterval(),它接受两个参数 - 一个调用每个刻度的函数,以及每个刻度需要多长时间(以毫秒为单位)。

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.

至于如何在 jquery 框架中专门编写它,嗯,我对 jquery 了解得不够多,无法告诉你。也许其他人可以更具体地帮助您,但同时您可以考虑扩展您已经与 onComplete 事件链接的 jquery 扩展,该事件的工作方式与我刚刚描述的一样。

回答by yckart

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

几天前我扩展了默认的 jQuery on-event-handler。如果在给定的时间间隔内未触发事件,它将一个或多个事件的事件处理函数附加到所选元素。如果您只想在延迟后触发回调,例如调整大小事件,或者其他情况,这将非常有用。 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 onor bind-event handler, except that you can pass an extra parameter as a last:

像任何其他onbind-event 处理程序一样使用它,除了您可以将额外的参数作为最后一个传递:

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

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

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