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

sar*_*rah 228 javascript jquery

我正在使用JQuery:

$(window).resize(function() { ... });
Run Code Online (Sandbox Code Playgroud)

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

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

bra*_*ahn 296

以下是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);
  };
})();
Run Code Online (Sandbox Code Playgroud)

用法:

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

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

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

  • 我<3 u,我在调整全屏(非html5)Highcharts图表的同时将其结合起来并且效果很好. (2认同)
  • 由于我从你的回答中获益匪浅,我认为我为社区的其他人分享了你提供的代码的工作原型:https://jsfiddle.net/h6h2pzpu/3/.享受每个人! (2认同)

Car*_*z T 134

我更喜欢创建一个活动:

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

以下是创建它的方法:

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

你可以在某个地方的全局javascript文件中使用它.


CMS*_*CMS 122

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

var delay = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  };
})();
Run Code Online (Sandbox Code Playgroud)

用法:

$(window).resize(function() {
    delay(function(){
      alert('Resize...');
      //...
    }, 500);
});
Run Code Online (Sandbox Code Playgroud)

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

  • 我认为如果多次使用这种方法可能会失败(例如,如果代码设置的不同部分回调到`$(window).resize`),因为它们都将共享`timer`变量.请参阅下面的答案以获得建议的解 (5认同)

小智 72

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

$(window).resize(_.debounce(function(){
    alert("Resized");
},500));
Run Code Online (Sandbox Code Playgroud)


小智 19

前面提到的一些解决方案并不适用于我,即使它们具有更广泛的用途.或者我发现这个在窗口调整大小上完成了这个工作:

$(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);
    });
});
Run Code Online (Sandbox Code Playgroud)


Irv*_*nin 12

非常感谢David Walsh,这是一个香草版的下划线辩护.

码:

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};
Run Code Online (Sandbox Code Playgroud)

用法简单:

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

$(window).on('resize', myEfficientFn);
Run Code Online (Sandbox Code Playgroud)

参考:http://davidwalsh.name/javascript-debounce-function


小智 6

实际上,正如我所知,当调整大小时,你不能完全做某些动作,只是因为你不知道未来用户的行为.但是你可以假设在两次调整大小事件之间经过了一段时间,所以如果你等待的次数多于此次并且没有调整大小,你可以调用你的函数.
想法是我们使用setTimeout和它的id来保存或删除它.例如,我们知道两次调整大小事件之间的时间是500ms,因此我们将等待750ms.

var a;
$(window).resize(function(){
  clearTimeout(a);
  a = setTimeout(function(){
    // call your function
  },750);
});
Run Code Online (Sandbox Code Playgroud)


小智 6

声明全局延迟侦听器:

var resize_timeout;

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

    resize_timeout = setTimeout(function(){
        $(window).trigger('resized');
    }, 250);
});
Run Code Online (Sandbox Code Playgroud)

下面根据需要使用侦听器进行resized事件:

$(window).on('resized', function(){
    console.log('resized');
});
Run Code Online (Sandbox Code Playgroud)


vis*_*hwa 5

这个对我有用。 请参阅此解决方案 - https://alvarotrigo.com/blog/firing-resize-event-only-once-when-resizing-is-finished/

var resizeId;
$(window).resize(function() {
    clearTimeout(resizeId);
    resizeId = setTimeout(doneResizing, 500);
});
function doneResizing(){
    //whatever we want to do 
}
Run Code Online (Sandbox Code Playgroud)