JavaScript/JQuery:$(窗口)。调整大小完成后如何触发?

JavaScript/JQuery:$(窗口)。调整大小完成后如何触发?,javascript,jquery,Javascript,Jquery,我使用JQuery的方式如下: $(window).resize(function() { ... }); 但是,如果用户通过拖动窗口边缘使其变大/变小来手动调整浏览器窗口的大小,则上面的.resize事件会多次触发 问题:如何在浏览器窗口大小调整完成后调用函数(以便事件只触发一次)?我使用以下函数延迟重复操作,它将适用于您的情况: var delay = (function(){ var timer = 0; return function(callback, ms){ cl

我使用JQuery的方式如下:

$(window).resize(function() { ... });
但是,如果用户通过拖动窗口边缘使其变大/变小来手动调整浏览器窗口的大小,则上面的
.resize
事件会多次触发


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

我使用以下函数延迟重复操作,它将适用于您的情况:

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(function () {
    waitForFinalEvent(function(){
      alert('Resize...');
      //...
    }, 500, "some unique string");
});

传递给它的回调函数将仅在指定的时间量后最后一次调用delay时执行,否则计时器将重置,我发现这对于其他用途很有用,例如检测用户何时停止键入,等等。

以下是对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() {
    delay(function(){
      alert('Resize...');
      //...
    }, 500);
});
$(window).resize(function () {
    waitForFinalEvent(function(){
      alert('Resize...');
      //...
    }, 500, "some unique string");
});
如果只调用一次,CMS的解决方案是好的,但是如果调用多次,例如,如果代码的不同部分设置了单独的回调以调整窗口大小,那么它将失败,因为它们共享
计时器
变量


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

我更喜欢创建一个事件:

$(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文件中的某个地方找到它。

假设在调整窗口大小后鼠标光标应该返回到文档,我们可以使用onmouseover事件创建类似回调的行为。不要忘记,此解决方案可能不会像预期的那样适用于触摸屏

var resizeTimer;
var resized = false;
$(window).resize(function() {
   clearTimeout(resizeTimer);
   resizeTimer = setTimeout(function() {
       if(!resized) {
           resized = true;
           $(document).mouseover(function() {
               resized = false;
               // do something here
               $(this).unbind("mouseover");
           })
       }
    }, 500);
});

如果安装了underline.js,您可以:

$(window).resize(_.debounce(function(){
    alert("Resized");
},500));

前面提到的一些解决方案对我不起作用,尽管它们具有更广泛的用途。或者,我已经在“窗口大小调整”上完成了这项工作:

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

用于延迟窗口大小调整事件的简单jQuery插件

语法: 添加新功能以调整事件大小

jQuery(window).resizeDelayed( func, delay, id ); // delay and id are optional
删除先前添加的函数(通过声明其ID)

jQuery(window).resizeDelayed( false, id );
删除所有功能

jQuery(window).resizeDelayed( false );
用法: 使用情况输出:

first event - should run after 0.4 seconds
newest event - should run after 0.5 second
third event - should run after 3.0 seconds
插件:
jQuery.fn.resizeDelayed=(函数(){
//>>>此部件仅运行一次-现在
var rd_funcs=[],rd_counter=1,foreachResizeFunction=function(func){for(rd_funcs中的var索引){func(index);};
//注册JQUERY调整事件处理程序
jQuery(窗口).resize(函数(){
//在每个注册函数上设置/重置超时
foreachResizeFunction(函数(索引){
//如果手动禁用此函数(通过调用jQuery(window).resizeDelayed(false,'id')),
//然后继续下一个
if(rd_funcs[索引]==false)
return;//继续;
//如果已经设置了setTimeout,这意味着我们应该重置它,因为它是在持续时间到期之前调用的
if(rd_funcs[index]。超时!==false)
clearTimeout(rd_funcs[index].timeout);
//根据持续时间设置新超时
rd_funcs[index].timeout=setTimeout(rd_funcs[index].func,rd_funcs[index].delay);
});
});

//事实上,正如我所知,在关闭resize(调整大小)时,您无法准确执行某些操作,因为您不知道未来用户的操作。但您可以假定两个调整大小事件之间经过的时间,因此如果您等待的时间稍长,并且没有进行调整大小,则可以调用您的函数。
我们的想法是使用
setTimeout
及其id来保存或删除它。例如,我们知道两个调整大小事件之间的时间为500ms,因此我们将等待750ms

var-a;
$(窗口)。调整大小(函数(){
清除超时(a);
a=设置超时(函数(){
//调用你的函数
},750);

})
非常感谢David Walsh,这里是下划线debounce的普通版本

代码:

简单用法:

var myEfficientFn = debounce(function() {
    // All the taxing stuff you do
}, 250);

$(window).on('resize', myEfficientFn);

参考:

它对我很有效。 见此解决方案-

var resizeId;
$(窗口)。调整大小(函数(){
clearTimeout(resizeId);
resizeId=setTimeout(DoneResize,500);
});
函数doneResizing(){
//不管我们想做什么

}
声明全局延迟侦听器:

var resize_timeout;

$(window).on('resize orientationchange', function(){
    clearTimeout(resize_timeout);

    resize_timeout = setTimeout(function(){
        $(window).trigger('resized');
    }, 250);
});
下面使用侦听器根据需要调整事件的大小:

$(window).on('resized', function(){
    console.log('resized');
});

这就是我所实现的:

$(窗口)。调整大小(函数(){ 设置超时(someFunction,500); }))

如果我们预计调整大小的时间小于
500ms,我们可以


祝你好运…

我认为如果多次使用,这种方法可能会失败(例如,如果代码设置的不同部分回调到
$(窗口)。调整大小
)因为它们都将共享
timer
变量。有关建议的解决方案,请参见下面的我的答案。非常好!就像你的答案一样!简单而优雅!适用于仅基于鼠标的桌面站点,但如果用户在移动设备上,并且从横向变为纵向,或者如果他们调整了触摸屏桌面上的窗口大小。您可以在最新windows操作系统(如Win Arrow Left Win Arrow Right等)上借助键盘调整浏览器窗口的大小。我绝对难以置信!因为我从您的回答中受益匪浅,我以为我为社区的其他人分享了您提供的代码的工作原型:。祝大家愉快!这s是完美的,但它会将实际函数的执行延迟毫秒(ms),这可能是非常不可取的。这就是完美的。有没有一种方法可以抓取最后一次调整大小,而不必在这些毫秒上进行中继?总之,这救了我一天:'))谢谢。即使你不想包含下划线,至少要抓住它的来源:在这里,去Bounce是正确的技术,这只是一个实现问题。如果下划线/Lodash已经是一个项目,这是一个更好的实现
$(window).on('resized', function(){
    console.log('resized');
});