如何等待'resize'事件的“结束”,然后再执行操作?

317

所以我目前使用类似以下的代码:

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

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


也许可以使用 .one(),这样它只会在所有调整大小完成后执行,而不是一遍又一遍地执行? - Brad Christie
5
当用户手动调整窗口大小(通过拖动)时,调整大小事件将被多次调用,因此使用.one()并不会有效。 - jessegavin
以上代码中可以移除匿名函数,以简化和提高速度:$(window).resize(resizedw)。 - Fornost
这里有一个jQuery库:https://github.com/nielse63/jquery.resizeend - rugk
26个回答

0
我编写了一个函数,当在任何调整大小事件中包装时,可以传递一个函数。它使用间隔,以便调整大小事件不会不断创建超时事件。这使得它可以独立于调整大小事件执行,除了应该在生产中删除的日志条目。

https://github.com/UniWrighte/resizeOnEnd/blob/master/resizeOnEnd.js

        $(window).resize(function(){
            //call to resizeEnd function to execute function on resize end.
    //can be passed as function name or anonymous function
            resizeEnd(function(){



    });

        });

        //global variables for reference outside of interval
        var interval = null;
        var width = $(window).width();
    var numi = 0; //can be removed in production
        function resizeEnd(functionCall){
            //check for null interval
            if(!interval){
                //set to new interval
                interval = setInterval(function(){
        //get width to compare
                    width2 = $(window).width();
        //if stored width equals new width
                    if(width === width2){
                        //clear interval, set to null, and call passed function
                        clearInterval(interval);
                        interval = null; //precaution
                        functionCall();

                    }
        //set width to compare on next interval after half a second
                    width = $(window).width();
                }, 500);

            }else{
                //logging that should be removed in production
                console.log("function call " + numi++ + " and inteval set skipped");

            }

}


0
var flag=true;
var timeloop;

$(window).resize(function(){
    rtime=new Date();
    if(flag){
        flag=false;
        timeloop=setInterval(function(){
            if(new Date()-rtime>100)
                myAction();
        },100);
    }
})
function myAction(){
    clearInterval(timeloop);
    flag=true;
    //any other code...
}

0

我不知道我的代码是否适用于其他人,但对我来说确实做得非常好。我通过分析Dolan Antenucci的代码得到了这个想法,因为他的版本对我来说不起作用,我真的希望它对某些人有所帮助。

var tranStatus = false;
$(window).resizeend(200, function(){
    $(".cat-name, .category").removeAttr("style");
    //clearTimeout(homeResize);
    $("*").one("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend",function(event) {
      tranStatus = true;
    });
    processResize();
});

function processResize(){
  homeResize = setInterval(function(){
    if(tranStatus===false){
        console.log("not yet");
        $("*").one("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend",function(event) {
            tranStatus = true;
        }); 
    }else{
        text_height();
        clearInterval(homeResize);
    }
  },200);
}

0

因为选择的答案实际上并未起作用...如果您不使用jQuery,这里有一个简单的节流函数,并提供了一个示例,展示如何在窗口调整大小时使用它

    function throttle(end,delta) {

    var base = this;

    base.wait = false;
    base.delta = 200;
    base.end = end;

    base.trigger = function(context) {

        //only allow if we aren't waiting for another event
        if ( !base.wait ) {

            //signal we already have a resize event
            base.wait = true;

            //if we are trying to resize and we 
            setTimeout(function() {

                //call the end function
                if(base.end) base.end.call(context);

                //reset the resize trigger
                base.wait = false;
            }, base.delta);
        }
    }
};

var windowResize = new throttle(function() {console.log('throttle resize');},200);

window.onresize = function(event) {
    windowResize.trigger();
}

0

这对我很有用,因为我不想使用任何插件。

$(window).resize(function() {
    var originalWindowSize = 0;
    var currentWidth = 0;

    var setFn = function () {
        originalWindowSize = $(window).width();
    };

    var checkFn = function () {
        setTimeout(function () {
            currentWidth = $(window).width();
            if (currentWidth === originalWindowSize) {
                console.info("same? = yes") 
                // execute code 
            } else {
                console.info("same? = no"); 
                // do nothing 
            }
        }, 500)
    };
    setFn();
    checkFn();
});

在窗口调整大小时调用“setFn”,该函数获取窗口的宽度并保存为“originalWindowSize”。然后调用“checkFn”,在500毫秒(或您喜欢的时间)后获取当前窗口大小,并将原始大小与当前大小进行比较,如果它们不相同,则窗口仍在调整大小。不要忘记在生产环境中删除控制台消息,并且(可选)可以使“setFn”自执行。

0

更新!

我创建的更好的替代方案在这里: https://dev59.com/f3E85IYBdhLWcg3wShaf#23692008 (支持“删除函数”)

原始帖子:

我编写了这个简单的函数来处理执行延迟,在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!
*/

你能澄清一下这里的用法吗?你是在建议一个人这样做吗:$(window).resize(function() { delay_exec('test1', 30, function() { ... delayed stuff here ... }); });?除此之外,代码非常干净。感谢分享。 :) - mhulse
你太棒了!感谢@Déján!一路加1。很酷的代码示例,从我测试的结果来看它非常好用。使用也很简单。再次感谢你的分享。 :) - mhulse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接