所以我目前使用的是:

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

但是在调整大小过程中,这个函数会被调用很多次。是否有可能在事件结束时捕获事件?


当前回答

更新!

我还创造了一个更好的选择: https://stackoverflow.com/a/23692008/2829600 (支持“删除功能”)

原来的帖子:

我写了这个简单的函数来处理执行中的延迟,在jQuery .scroll()和.resize()中很有用,所以callback_f只会对特定的id字符串运行一次。

function delay_exec( id, wait_time, callback_f ){

    // IF WAIT TIME IS NOT ENTERED IN FUNCTION CALL,
    // SET IT TO DEFAULT VALUE: 0.5 SECOND
    if( typeof wait_time === "undefined" )
        wait_time = 500;

    // CREATE GLOBAL ARRAY(IF ITS NOT ALREADY CREATED)
    // WHERE WE STORE CURRENTLY RUNNING setTimeout() FUNCTION FOR THIS ID
    if( typeof window['delay_exec'] === "undefined" )
        window['delay_exec'] = [];

    // RESET CURRENTLY RUNNING setTimeout() FUNCTION FOR THIS ID,
    // SO IN THAT WAY WE ARE SURE THAT callback_f WILL RUN ONLY ONE TIME
    // ( ON LATEST CALL ON delay_exec FUNCTION WITH SAME ID  )
    if( typeof window['delay_exec'][id] !== "undefined" )
        clearTimeout( window['delay_exec'][id] );

    // SET NEW TIMEOUT AND EXECUTE callback_f WHEN wait_time EXPIRES,
    // BUT ONLY IF THERE ISNT ANY MORE FUTURE CALLS ( IN wait_time PERIOD )
    // TO delay_exec FUNCTION WITH SAME ID AS CURRENT ONE
    window['delay_exec'][id] = setTimeout( callback_f , wait_time );
}


// USAGE

jQuery(window).resize(function() {

    delay_exec('test1', 1000, function(){
        console.log('1st call to delay "test1" successfully executed!');
    });

    delay_exec('test1', 1000, function(){
        console.log('2nd call to delay "test1" successfully executed!');
    });

    delay_exec('test1', 1000, function(){
        console.log('3rd call to delay "test1" successfully executed!');
    });

    delay_exec('test2', 1000, function(){
        console.log('1st call to delay "test2" successfully executed!');
    });

    delay_exec('test3', 1000, function(){
        console.log('1st call to delay "test3" successfully executed!');
    });

});

/* RESULT
3rd call to delay "test1" successfully executed!
1st call to delay "test2" successfully executed!
1st call to delay "test3" successfully executed!
*/

其他回答

一种解决方案是用一个函数来扩展jQuery,例如:resize

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

示例用法:

美元(窗口)。大小(myHandler, 300);

Mark Coleman的答案当然比所选的答案要好得多,但如果你想避免超时ID的全局变量(Mark回答中的doit变量),你可以做以下其中之一:

(1)使用立即调用的函数表达式(IIFE)来创建闭包。

$(window).resize((function() { // This function is immediately invoked
                               // and returns the closure function.
    var timeoutId;
    return function() {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(function() {
            timeoutId = null; // You could leave this line out.
            // Code to execute on resize goes here.
        }, 100);
    };
})());

(2)使用事件处理函数的属性。

$(window).resize(function() {
    var thisFunction = arguments.callee;
    clearTimeout(thisFunction.timeoutId);
    thisFunction.timeoutId = setTimeout(function() {
        thisFunction.timeoutId = null; // You could leave this line out.
        // Code to execute on resize goes here.
    }, 100);
});

我自己写了一个小包装函数…

onResize  =   function(fn) {
    if(!fn || typeof fn != 'function')
        return 0;

    var args    = Array.prototype.slice.call(arguments, 1);

    onResize.fnArr    = onResize.fnArr || [];
    onResize.fnArr.push([fn, args]);

    onResize.loop   = function() {
        $.each(onResize.fnArr, function(index, fnWithArgs) {
            fnWithArgs[0].apply(undefined, fnWithArgs[1]);
        });
    };

    $(window).on('resize', function(e) {
        window.clearTimeout(onResize.timeout);
        onResize.timeout    = window.setTimeout("onResize.loop();", 300);
    });
};

用法如下:

var testFn  = function(arg1, arg2) {
    console.log('[testFn] arg1: '+arg1);
    console.log('[testFn] arg2: '+arg2);
};

// document ready
$(function() {
    onResize(testFn, 'argument1', 'argument2');
});

有一个比计算两次调用之间的增量时间更简单的方法来在调整大小结束时执行函数,简单地像这样做:

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

function resizedEnded(){
    ...
}

和Angular2的等价函数:

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

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

就窗口管理器而言,每个调整大小事件都是它自己的消息,具有不同的开始和结束,因此从技术上讲,每次调整窗口大小时,它都是结束。

话虽如此,也许你想推迟你的延续?举个例子。

var t = -1;
function doResize()
{
    document.write('resize');
}
$(document).ready(function(){
    $(window).resize(function(){
        clearTimeout(t);
        t = setTimeout(doResize, 1000);
    });
});