jQuery - 如何等待'resize'事件的'end'然后再执行一个动作?

Rel*_*lla 222 html javascript jquery resize jquery-events

所以我目前使用的东西如下:

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

但是在调整大小过程的过程中会多次调用它.是否可以在事件结束时捕获事件?

Mar*_*man 496

你可以使用setTimeout()clearTimeout()

function resizedw(){
    // Haven't resized in 100ms!
}

var doit;
window.onresize = function(){
  clearTimeout(doit);
  doit = setTimeout(resizedw, 100);
};
Run Code Online (Sandbox Code Playgroud)

关于jsfiddle的代码示例.

  • 这是**debounce**概念的非常简单的实现(http://unscriptable.com/2009/03/20/debouncing-javascript-methods/).Paul Irish(和其他人)提出了一个更有效的解决方案,它不处理"不必要的"调整大小事件:http://www.paulirish.com/2009/throttled-smartresize-jquery-event-handler/ (12认同)
  • 这是一个很好的答案.它做了我推荐的插件,只是没有插件. (6认同)

Dol*_*cci 167

我很满意以下建议:http://forum.jquery.com/topic/the-resizeend-event

这是代码,所以你不必挖掘他的帖子的链接和来源:

var rtime;
var timeout = false;
var delta = 200;
$(window).resize(function() {
    rtime = new Date();
    if (timeout === false) {
        timeout = true;
        setTimeout(resizeend, delta);
    }
});

function resizeend() {
    if (new Date() - rtime < delta) {
        setTimeout(resizeend, delta);
    } else {
        timeout = false;
        alert('Done resizing');
    }               
}
Run Code Online (Sandbox Code Playgroud)

感谢sime.vidas的代码!

  • 人们可能希望将日期更改为类似“new Date(-1E12)”的内容——即 JSLint 警告使用“00”。 (2认同)

Roy*_*hoa 76

这是我根据@Mark Coleman回答的代码:

$(window).resize(function() {
    clearTimeout(window.resizedFinished);
    window.resizedFinished = setTimeout(function(){
        console.log('Resized finished.');
    }, 250);
});
Run Code Online (Sandbox Code Playgroud)

谢谢马克!

  • 不错的方法。还提到[这里](https://css-tricks.com/snippets/jquery/done-resizing-event/),区别在于没有对超级变量 _window_ 进行任何修改。 (2认同)
  • @AlwinKesler - 在你的例子中,变量`resizeTimer`是一个全局变量,这意味着它没有定义`window`,所以它与这里完全相同,只是这个例子更好,因为你不需要在外部定义变量.将这个变量添加到`window`对象也是有意义的,因为那是事件监听器绑定到的Object. (2认同)

jes*_*vin 34

Internet Explorer提供resizeEnd事件.在调整大小时,其他浏览器会多次触发调整大小事件.

这里还有其他很好的答案,展示了如何使用setTimeout和.throttle,来自lodash和下划线的.debounce方法,所以我将提到Ben Alman的油门 - 去抖jQuery插件,它完成了你所追求的.

假设您在调整大小后想要触发此功能:

function onResize() {
  console.log("Resize just happened!");
};
Run Code Online (Sandbox Code Playgroud)

节流示例
在以下示例中,onResize()仅在窗口调整大小期间每250毫秒调用一次.

$(window).resize( $.throttle( 250, onResize) );
Run Code Online (Sandbox Code Playgroud)

去抖动示例
在以下示例中,onResize()仅在窗口大小调整操作结束时调用一次.这与@Mark在他的回答中提出的结果相同.

$(window).resize( $.debounce( 250, onResize) );
Run Code Online (Sandbox Code Playgroud)


Rif*_*fat 26

使用Underscore.js有一个优雅的解决方案因此,如果您在项目中使用它,您可以执行以下操作 -

$( window ).resize( _.debounce( resizedw, 500 ) );
Run Code Online (Sandbox Code Playgroud)

这应该足够:)但是,如果你有兴趣阅读更多内容,你可以查看我的博客文章 - http://rifatnabi.com/post/detect-end-of-jquery-resize-event-using-underscore -debounce(deadlink)


Ant*_*iry 10

在调整大小结束时执行函数的方法比计算两次调用之间的时间差要简单得多,只需这样做:

var resizeId;
$(window).resize(function() {
    clearTimeout(resizeId);
    resizeId = setTimeout(resizedEnded, 500);
});

function resizedEnded(){
    ...
}
Run Code Online (Sandbox Code Playgroud)

相当于Angular2

private resizeId;
@HostListener('window:resize', ['$event'])
onResized(event: Event) {
  clearTimeout(this.resizeId);
  this.resizeId = setTimeout(() => {
    // Your callback method here.
  }, 500);
}
Run Code Online (Sandbox Code Playgroud)

对于 angular 方法,使用 中的() => { }符号setTimeout来保留作用域,否则您将无法进行任何函数调用或使用this.


Xma*_*cal 7

您可以将引用ID存储到任何setInterval或setTimeout.像这样:

var loop = setInterval(func, 30);

// some time later clear the interval
clearInterval(loop);
Run Code Online (Sandbox Code Playgroud)

要在没有"全局"变量的情况下执行此操作,可以向函数本身添加局部变量.例如:

$(window).resize(function() {
    clearTimeout(this.id);
    this.id = setTimeout(doneResizing, 500);
});

function doneResizing(){
  $("body").append("<br/>done!");   
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*ora 7

一个解决方案是使用函数扩展jQuery,例如: resized

$.fn.resized = function (callback, timeout) {
    $(this).resize(function () {
        var $this = $(this);
        if ($this.data('resizeTimeout')) {
            clearTimeout($this.data('resizeTimeout'));
        }
        $this.data('resizeTimeout', setTimeout(callback, timeout));
    });
};
Run Code Online (Sandbox Code Playgroud)

样品用法:

$(window).resized(myHandler, 300);