Programing

'크기 조정'이벤트의 '종료'를 기다린 다음 작업을 수행하는 방법은 무엇입니까?

lottogame 2020. 4. 23. 07:40
반응형

'크기 조정'이벤트의 '종료'를 기다린 다음 작업을 수행하는 방법은 무엇입니까?


그래서 나는 현재 다음과 같은 것을 사용합니다 :

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

그러나 크기 조정 프로세스가 진행되는 동안 여러 번 호출됩니다. 끝날 때 이벤트를 잡을 수 있습니까?


다음 권장 사항으로 운이 좋았습니다 .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');
    }               
}

코드 주셔서 감사 sime.vidas!


당신이 사용할 수있는 setTimeout()clearTimeout()

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

var doit;
window.onresize = function(){
  clearTimeout(doit);
  doit = setTimeout(resizedw, 100);
};

jsfiddle의 코드 예제 .


이것은 @Mark Coleman의 답변에 따라 작성한 코드입니다.

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

고마워 마크!


Internet Explorer는 resizeEnd 이벤트를 제공합니다 . 크기를 조정하는 동안 다른 브라우저는 크기 조정 이벤트를 여러 번 트리거합니다.

여기에 setTimeout과 .throttle 을 사용하는 방법을 보여주는 다른 훌륭한 답변이 있습니다 .lodash 와 밑줄에서 .debounce 메소드를 사용하므로 Ben Alman의 throttle-debounce jQuery 플러그인에 대해 언급하겠습니다 .

크기 조정 후 트리거하려는이 기능이 있다고 가정하십시오.

function onResize() {
  console.log("Resize just happened!");
};

스로틀 예제
다음 예제 에서는 onResize()창 크기를 조정하는 동안 250 밀리 초마다 한 번 씩만 호출됩니다.

$(window).resize( $.throttle( 250, onResize) );

디 바운스 예
다음 에서는 onResize()창 크기 조정 작업이 끝날 때 한 번만 호출됩니다. 이것은 @Mark가 그의 답변에서 제시하는 것과 동일한 결과를 얻습니다.

$(window).resize( $.debounce( 250, onResize) );

Underscore.js를 사용하는 우아한 솔루션 이 있으므로 프로젝트에서 사용하는 경우 다음을 수행 할 수 있습니다.

$( window ).resize( _.debounce( resizedw, 500 ) );

이것으로 충분해야합니다 :),하지만 그것에 대해 더 자세히 알고 싶다면 내 블로그 게시물을 확인할 수 있습니다-http: //rifatnabi.com/post/detect-end-of-jquery-resize-event-using-underscore -디 바운스 (데드 링크)


setInterval 또는 setTimeout에 대한 참조 ID를 저장할 수 있습니다. 이처럼 :

var loop = setInterval(func, 30);

// some time later clear the interval
clearInterval(loop);

"전역"변수없이이를 수행하려면 함수 자체에 로컬 변수를 추가 할 수 있습니다. 전의:

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

function doneResizing(){
  $("body").append("<br/>done!");   
}

한 가지 해결책은 다음과 같은 함수로 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));
    });
};

샘플 사용법 :

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


당신은 사용할 수 있습니다 setTimeout()clearTimeout()와 함께 jQuery.data:

$(window).resize(function() {
    clearTimeout($.data(this, 'resizeTimer'));
    $.data(this, 'resizeTimer', setTimeout(function() {
        //do something
        alert("Haven't resized in 200ms!");
    }, 200));
});

최신 정보

jQuery의 기본 (& ) 이벤트 핸들러 를 향상시키는 확장 기능작성했습니다 . 지정된 간격 동안 이벤트가 트리거되지 않은 경우 하나 이상의 이벤트에 대한 이벤트 핸들러 기능을 선택된 요소에 첨부합니다. resize 이벤트와 같이 지연된 후에 만 ​​콜백을 시작하려는 경우에 유용합니다. https://github.com/yckart/jquery.unevent.jsonbind

;(function ($) {
    var methods = { on: $.fn.on, bind: $.fn.bind };
    $.each(methods, function(k){
        $.fn[k] = function () {
            var args = [].slice.call(arguments),
                delay = args.pop(),
                fn = args.pop(),
                timer;

            args.push(function () {
                var self = this,
                    arg = arguments;
                clearTimeout(timer);
                timer = setTimeout(function(){
                    fn.apply(self, [].slice.call(arg));
                }, delay);
            });

            return methods[k].apply(this, isNaN(delay) ? arguments : args);
        };
    });
}(jQuery));

추가 매개 변수를 마지막으로 전달할 수 있다는 점을 제외하고 다른 on또는 bind-event 핸들러 와 같이 사용하십시오 .

$(window).on('resize', function(e) {
    console.log(e.type + '-event was 200ms not triggered');
}, 200);

http://jsfiddle.net/ARTsinn/EqqHx/


이것은 위의 Dolan 코드에 대한 수정입니다. 크기 조정이 시작될 때 창 크기를 확인하고 크기가 여백보다 크거나 작은 경우 크기 조정이 끝날 때의 크기와 비교하는 기능을 추가했습니다 ( 예를 들어 1000) 다시로드됩니다.

var rtime = new Date(1, 1, 2000, 12,00,00);
var timeout = false;
var delta = 200;
var windowsize = $window.width();
var windowsizeInitial = $window.width();

$(window).on('resize',function() {
    windowsize = $window.width();
    rtime = new Date();
    if (timeout === false) {
            timeout = true;
            setTimeout(resizeend, delta);
        }
});

function resizeend() {
if (new Date() - rtime < delta) {
    setTimeout(resizeend, delta);
    return false;
} else {
        if (windowsizeInitial > 1000 && windowsize > 1000 ) {
            setTimeout(resizeend, delta);
            return false;
        }
        if (windowsizeInitial < 1001 && windowsize < 1001 ) {
            setTimeout(resizeend, delta);
            return false;
        } else {
            timeout = false;
            location.reload();
        }
    }
    windowsizeInitial = $window.width();
    return false;
}

Mark Coleman의 답변은 선택한 답변보다 훨씬 낫지 만 시간 초과 ID ( doitMark의 답변 변수)에 대한 전역 변수를 피 하려면 다음 중 하나를 수행하십시오.

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

나는 내 자신의 litte wrapper 함수를 작성했다 ...

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');
});

(function(){
    var special = jQuery.event.special,
        uid1 = 'D' + (+new Date()),
        uid2 = 'D' + (+new Date() + 1);

    special.resizestart = {
        setup: function() {
            var timer,
                handler =  function(evt) {
                    var _self = this,
                        _args = arguments;
                    if (timer) {
                        clearTimeout(timer);
                    } else {
                        evt.type = 'resizestart';
                        jQuery.event.handle.apply(_self, _args);
                    }

                    timer = setTimeout( function(){
                        timer = null;
                    }, special.resizestop.latency);
                };
            jQuery(this).bind('resize', handler).data(uid1, handler);
        },
        teardown: function(){
            jQuery(this).unbind( 'resize', jQuery(this).data(uid1) );
        }
    };

    special.resizestop = {
        latency: 200,
        setup: function() {
            var timer,
                handler = function(evt) {
                    var _self = this,
                        _args = arguments;
                    if (timer) {
                        clearTimeout(timer);
                    }
                    timer = setTimeout( function(){
                        timer = null;
                        evt.type = 'resizestop';
                        jQuery.event.handle.apply(_self, _args);
                    }, special.resizestop.latency);
                };

            jQuery(this).bind('resize', handler).data(uid2, handler);
        },
        teardown: function() {
            jQuery(this).unbind( 'resize', jQuery(this).data(uid2) );
        }
    };
})();

$(window).bind('resizestop',function(){
    //...
});

그럼, 지금까지의 윈도우 매니저에 관한 한, 각 resize 이벤트는 자신의 메시지는 너무 기술적으로, 윈도우의 크기가 변경 될 때마다, 그것은, 별개의 시작과 끝입니다 입니다 끝.

당신은 당신의 연속에 지연을 설정하고 싶습니까? 다음은 예입니다.

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

다음은 창 객체에서 'resizestart'및 'resizeend'이벤트를 모두 트리거하는 매우 간단한 스크립트입니다.

날짜와 시간을 정리할 필요가 없습니다.

d변수가 크기 조정 종료 이벤트를 트리거하기 전에 크기 조정 이벤트 사이의 밀리 세컨드 수를 나타냅니다, 당신은 종료 이벤트가 얼마나 민감한 변경하려면이 함께 재생할 수 있습니다.

이러한 이벤트를 들으려면 다음을 수행하십시오.

크기 조정 시작 : $(window).on('resizestart', function(event){console.log('Resize Start!');});

크기 조정 : $(window).on('resizeend', function(event){console.log('Resize End!');});

(function ($) {
    var d = 250, t = null, e = null, h, r = false;

    h = function () {
        r = false;
        $(window).trigger('resizeend', e);
    };

    $(window).on('resize', function (event) {
        e = event || e;
        clearTimeout(t);

        if (!r) {
            $(window).trigger('resizestart', e);
            r = true;
        }

        t = setTimeout(h, d);
    });
}(jQuery));

선택한 답변이 실제로 작동하지 않기 때문에 .. 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();
}

나는 플러그인을 사용하고 싶지 않기 때문에 나를 위해 일했다.

$(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"로 저장하십시오. 그런 다음 500ms (또는 기본 설정)가 현재 창 크기를 얻은 후 원본과 현재 창을 비교하여 동일하지 않은 경우 창 크기를 계속 조정하는 "checkFn"을 호출하십시오. 프로덕션 환경에서 콘솔 메시지를 제거하는 것을 잊지 마십시오. (선택 사항) "setFn"자체 실행을 만들 수 있습니다.


var resizeTimer;
$( window ).resize(function() {
    if(resizeTimer){
        clearTimeout(resizeTimer);
    }
    resizeTimer = setTimeout(function() {
        //your code here
        resizeTimer = null;
        }, 200);
    });

이것은 내가 크롬에서하려고했던 일에 효과적이었습니다. 마지막 크기 조정 이벤트 후 200ms까지 콜백이 발생하지 않습니다.


최신 정보!

나도 만든 더 나은 대안은 다음과 같습니다. 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!
*/

창의 ResizeStartResizeEnd 이벤트

http://jsfiddle.net/04fLy8t4/

사용자 DOM 요소에서 두 가지 이벤트를 처리하는 기능을 구현했습니다.

  1. 크기 조정 시작
  2. 크기 조정

암호:

var resizeEventsTrigger = (function () {
    function triggerResizeStart($el) {
        $el.trigger('resizestart');
        isStart = !isStart;
    }

    function triggerResizeEnd($el) {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(function () {
            $el.trigger('resizeend');
            isStart = !isStart;
        }, delay);
    }

    var isStart = true;
    var delay = 200;
    var timeoutId;

    return function ($el) {
        isStart ? triggerResizeStart($el) : triggerResizeEnd($el);
    };

})();

$("#my").on('resizestart', function () {
    console.log('resize start');
});
$("#my").on('resizeend', function () {
    console.log('resize end');
});

window.onresize = function () {
    resizeEventsTrigger( $("#my") );
};

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...
}

나는 내 코드가 다른 사람을 위해 작동한다는 것을 모르지만 실제로 나를 위해 훌륭한 일을하고 있습니다. 그의 버전이 나를 위해 작동하지 않기 때문에 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);
}

크기 조정 이벤트에 래핑 될 때 함수를 전달하는 함수를 작성했습니다. 크기 조정이 시간 초과 이벤트를 지속적으로 생성하지 않도록 간격을 사용합니다. 이를 통해 프로덕션에서 제거해야하는 로그 항목 이외의 크기 조정 이벤트와 독립적으로 수행 할 수 있습니다.

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");

            }

}


이것은 반복 작업을 지연시키는 데 사용하는 것으로 코드의 여러 위치에서 호출 할 수 있습니다.

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

용법:

$(window).resize(function () { 
   debounce(function() {
          //...
    }, 500);
});

참고 URL : https://stackoverflow.com/questions/5489946/how-to-wait-for-the-end-of-resize-event-and-only-then-perform-an-action

반응형