【问题标题】:Resize event firing multiple times while dragging the resize handle拖动调整大小手柄时多次触发调整大小事件
【发布时间】:2010-10-14 14:58:00
【问题描述】:

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

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

我在他的网站上添加了一条评论,但它们是经过审核的,所以你可能还看不到它。

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

【问题讨论】:

标签: jquery resize window jquery-events


【解决方案1】:

这样的代码怎么样:

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
});

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

【讨论】:

  • 对不起,但我不明白这是如何工作的...... TO 最初如何变得不假?我看到它是假的,然后它变得不假的唯一方法就是在它已经不假之后。
  • 编辑:没关系,我认为 TO = setTimout 是 if 的一部分。不使用花括号的坏习惯 - 使代码更难快速阅读。只是大括号,伙计。
【解决方案2】:

从并发解决方案中借鉴一些想法来管理来自浏览器的大量事件。

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

这样,您每秒只处理一次最新事件(或根据您的要求在其他一段时间内)。如果用户在调整大小的过程中暂停,它将处理。如果用户完成,它将处理。

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

【讨论】:

  • jQuery 插件就是这样做的,但是它不能正确地做到这一点。
  • 我没有足够的知识来正确地做这件事。因此,为什么我在这里要求知识。 :) 顺便说一句,我不追求宽度、高度、顶部、左侧。我知道调整大小事件何时完成(意味着用户放开浏览器的调整大小句柄)
  • 好吧,这种事情真的很容易做到,所以不要气馁。转到这里:w3schools.com/htmldom/met_win_settimeout.asp 它会让你开始使用 SetTimeout 函数,这正是你在这种情况下所需要的。当你得到一个 resize 事件时,不要直接处理它......
  • (续) ... 仅在经过一定时间后处理事件。这样你就不会太频繁地处理事件。
  • @TetraDev:如果我的目标只是提供答案,我会的;但是,我的目标是教育。
【解决方案3】:

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

【讨论】:

  • 这就是我在发布原始问题后不久为我的解决方案编写的代码,我添加了一个计时器,以确保事件更新只会在 x 毫秒内结束。
  • @DMCS 如果这就是您最终所做的,那这不是正确的答案吗? :)
  • 根据我在 2011 年 3 月 20 日从 Welbog 收到的答案,我自己编写了代码。 2011 年 4 月 9 日,我接受了他们的回答。然后,在我接受了他们的答案之后,您于 2011 年 6 月 16 日回答。我没有使用 Paul 的插件,我在 2011 年 3 月 20 日至 4 月 9 日之间的某个地方编写了自己的插件。您迟到的答案得到了两个支持,这相当于指向一个已接受的答案。
  • @DMCS 嗯……值得一试:)
【解决方案4】:

如果您喜欢图书馆,您应该检查下划线,下划线已经满足您的需求,并且您的项目中可能还会有更多。

以下是下划线去抖器工作原理的示例:

// 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

然后在调整窗口大小时调用去抖动函数

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

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

【讨论】:

  • 感谢对 underscore.js 的有用介绍
【解决方案5】:

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

【讨论】:

  • 如何知道用户何时暂停调整大小? javascript/jQuery 中获取用户已暂停信息的确切语法是什么?
  • 当元素的宽度和高度在指定时间段内(即您设置的超时时间跨度)没有改变时,您知道调整大小何时“暂停”。
【解决方案6】:

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

编辑:

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

至于如何在 jquery 框架中专门编写它,好吧,我对 jquery 的了解还不够,无法告诉你。也许其他人可以更具体地帮助您,但同时您可以考虑扩展您已经与 onComplete 事件链接的 jquery 扩展,就像我刚才描述的那样。

【讨论】:

  • 一个 onComplete 事件会非常好。但是,javascript(或 jQuery)的语法/命令是什么?
  • 我对 jquery 的了解不够,无法为您提供具体的答案,但 Russ Cam 在他的解决方案中提出了大致相同的建议。我会在编辑中解释。
【解决方案7】:

几天前我扩展了默认的 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));

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 2021-04-15
    • 2018-10-01
    • 1970-01-01
    • 2012-04-24
    • 2011-04-02
    相关资源
    最近更新 更多