JavaScript/JQuery:$(window).resize 如何在调整大小完成后触发?

IT技术 javascript jquery
2021-01-30 06:07:32

我正在使用 JQuery:

$(window).resize(function() { ... });

但是,似乎如果该人通过拖动窗口边缘使其变大/变小来手动调整浏览器窗口的大小,则.resize上述事件会多次触发。

问题:如何在浏览器窗口调整大小完成后调用函数(以便事件只触发一次)?

6个回答

这是 CMS 解决方案的修改,可以在代码中的多个位置调用:

var waitForFinalEvent = (function () {
  var timers = {};
  return function (callback, ms, uniqueId) {
    if (!uniqueId) {
      uniqueId = "Don't call this twice without a uniqueId";
    }
    if (timers[uniqueId]) {
      clearTimeout (timers[uniqueId]);
    }
    timers[uniqueId] = setTimeout(callback, ms);
  };
})();

用法:

$(window).resize(function () {
    waitForFinalEvent(function(){
      alert('Resize...');
      //...
    }, 500, "some unique string");
});

CMS 的解决方案如果您只调用一次就很好,但是如果您多次调用它,例如,如果代码的不同部分设置了单独的回调来调整窗口大小,那么它将失败 b/c 它们共享timer变量。

通过此修改,您为每个回调提供一个唯一 ID,这些唯一 ID 用于将所有超时事件分开。

由于我从您的回答中受益匪浅,我以为我为社区的其他人分享了您提供的代码的工作原型:jsfiddle.net/h6h2pzpu/3享受每一个人!
2021-03-18 06:07:32
我 <3 u,我在调整全屏(非 html5)Highcharts 图表的大小时结合了这个,效果很好。
2021-04-02 06:07:32
这一切都很完美,但它延迟了实际函数的执行毫秒 (ms),这可能是非常不受欢迎的。
2021-04-03 06:07:32
这只是完美有没有办法抓住最后一次调整大小而不必中继那些毫秒?无论如何,这只是拯救了我的一天:') 谢谢。
2021-04-05 06:07:32
绝对不可思议!
2021-04-06 06:07:32

我更喜欢创建一个事件:

$(window).bind('resizeEnd', function() {
    //do something, window hasn't changed size in 500ms
});

这是您创建它的方法:

 $(window).resize(function() {
        if(this.resizeTO) clearTimeout(this.resizeTO);
        this.resizeTO = setTimeout(function() {
            $(this).trigger('resizeEnd');
        }, 500);
    });

您可以将其放在某个全局 javascript 文件中。

这对我不起作用,但 DusanV 的回答完成了这项工作
2021-03-18 06:07:32
这允许您在所有地方绑定到该事件,而不仅仅是在一个函数中,假设您有多个页面/.js 文件当然需要对其进行单独的反应
2021-04-02 06:07:32
我使用了这个解决方案。但从长远来看,我想实现与 brahn 的解决方案相同的解决方案。
2021-04-08 06:07:32

我使用以下功能来延迟重复操作,它适用于您的情况:

var delay = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  };
})();

用法:

$(window).resize(function() {
    delay(function(){
      alert('Resize...');
      //...
    }, 500);
});

传递给它的回调函数只有在指定时间后最后一次调用延迟时才会执行,否则计时器将被重置,我发现这对于其他目的很有用,例如检测用户何时停止输入等。 ..

我认为如果多次使用这种方法可能会失败(例如,如果代码设置的不同部分回调到$(window).resize),因为它们都将共享timer变量。有关建议的解决方案,请参阅下面的答案。
2021-03-12 06:07:32
非常好!奇迹般有效!喜欢你的答案......简单而优雅!
2021-03-25 06:07:32

如果你安装了 Underscore.js,你可以:

$(window).resize(_.debounce(function(){
    alert("Resized");
},500));
这就是我现在正在使用的,
2021-03-17 06:07:32
即使您不想包含 Underscore,也至少要为此获取源代码:underscorejs.org/docs/underscore.html#section-67
2021-03-26 06:07:32
去抖动是这里的正确技术,这只是一个实现问题。如果 Underscore/Lodash 已经是一个项目依赖项,那么这是更好的实现。
2021-03-29 06:07:32

前面提到的一些解决方案对我不起作用,即使它们具有更广泛的用途。或者,我发现这个可以调整窗口大小的工作:

$(window).bind('resize', function(e){
    window.resizeEvt;
    $(window).resize(function(){
        clearTimeout(window.resizeEvt);
        window.resizeEvt = setTimeout(function(){
        //code to do after window is resized
        }, 250);
    });
});
只有你的例子对我有用......上面的其他人没有!我不确定为什么没有选择您的答案。
2021-03-13 06:07:32
lightbyte,这是因为每次调用该函数时都必须停止之前的事件。
2021-03-24 06:07:32
Mumbo Jumbo,我认为是因为其他人专注于泛化,寻找任何此类问题的解决方案(函数的多次调用)。
2021-03-27 06:07:32
我不明白为什么要在 resize 事件中捕获 resize 事件,但它也适用于我......
2021-03-29 06:07:32