จะรอเหตุการณ์ 'สิ้นสุด' ของ 'ปรับขนาด' และดำเนินการอย่างไร


243

ดังนั้นฉันจึงใช้บางสิ่งเช่น:

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

แต่สิ่งนี้ถูกเรียกหลายครั้งในขณะที่กระบวนการปรับขนาดดำเนินต่อไป เป็นไปได้หรือไม่ที่จะจับเหตุการณ์เมื่อมันจบลง?


อาจจะแนบโดยใช้.one()ดังนั้นมันจะทำงานหลังจากการปรับขนาดทั้งหมดเสร็จสิ้นและไม่มากเกินไป?
แบรดคริสตี้

5
เมื่อผู้ใช้ปรับขนาดหน้าต่างด้วยตนเอง (โดยการลาก) เหตุการณ์การปรับขนาดจะถูกเรียกมากกว่าหนึ่งครั้งดังนั้นการใช้. one () จะไม่ได้ผลจริงๆ
jessegavin

การใช้งานฟังก์ชั่นที่ไม่ระบุชื่อในด้านบนสามารถลบออกได้เพื่อความง่ายและความรวดเร็วที่ขอบ: $ (หน้าต่าง). resize (resizedw)
Fornost

นี่คือห้องสมุด jQuery สำหรับสิ่งนี้: github.com/nielse63/jquery.resizeend
rugk

คำตอบ:


177

ฉันโชคดีกับคำแนะนำต่อไปนี้: 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 สำหรับรหัส!


1
หนึ่งอาจต้องการที่จะเปลี่ยนวันนี้เพื่อสิ่งที่ชอบnew Date(-1E12)- คือ JSLint 00เตือนเกี่ยวกับการใช้
elundmark

ขอบคุณ elundmark ฉันได้เปลี่ยนอินสแตนซ์ของวันที่ให้ใช้ 0 เดียว; หวังว่าจะไม่สร้างการร้องเรียน
Dolan Antenucci

@ เครื่องหมายหรือใช้ + การดำเนินการ rtime: Date; .... if (+new Date() - +rtime < delta)และในการทำงาน resizeend typescript resizeend=()=>ควรจะเป็นฟังก์ชั่นลูกศรเช่นนี้ เพราะฟังก์ชั่นปรับขนาดthisอ้างอิงวัตถุหน้าต่าง
Muhammet Can TONBUL

517

คุณสามารถใช้setTimeout()และclearTimeout()

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

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

ตัวอย่างโค้ดบนjsfiddle


7
นี่คือคำตอบที่ดี มันเป็นสิ่งที่ปลั๊กอินที่ฉันแนะนำจะทำโดยไม่มีปลั๊กอิน
jessegavin

ฉันคิดว่าวิธีเดียวที่จะปรับปรุงสิ่งนี้ได้จริงๆคือตรวจจับการเคลื่อนไหวของเมาส์ ฉันสงสัยว่าการขุดเข้าไปจะไม่ได้ผลดี
Michael Haren

ใช้งานได้หรือไม่ถ้าการปรับขนาดเสร็จสิ้นภายในไม่กี่วินาที ฟังก์ชั่นของฉันถูกเรียกใช้เมื่อฉันพยายามใช้สิ่งนี้ (ฉันช้าด้วยการปรับขนาดหน้าต่างของฉันแม้ว่า)
Dolan Antenucci

@MichaelHaren เนื่องจากการจัดการขนาดใหม่โดยทั่วไปแล้วการ$(document)ตรวจจับเมาส์จะ จำกัด เฉพาะผู้ใช้ที่ใช้ Microsoft Windows และ Internet Explorer รุ่นที่มีช่องโหว่: iedataleak.spider.io/demo
Alastair

12
นี่เป็นการใช้แนวคิดdebounceง่ายๆ( unscriptable.com/2009/03/20/debouncing-javascript-methods ) Paul Irish (และคนอื่น ๆ ) ได้นำเสนอโซลูชันที่มีประสิทธิภาพมากขึ้นซึ่งไม่ได้จัดการกับการปรับขนาดเหตุการณ์ 'ไม่จำเป็น': paulirish.com/2009/throttled-smartresize-jquery-event-handler
rmoestl

78

นี่คือรหัสที่ฉันเขียนตาม @ Mark Coleman คำตอบ:

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

ขอบคุณมาร์ค!


1
ผู้อนุมัติที่ดี ยังกล่าวถึงในที่นี้ด้วยความแตกต่างที่ไม่มีการแก้ไขกับหน้าต่างตัวแปรพิเศษ
Alwin Kesler

2
@AlwinKesler - ในตัวอย่างของคุณตัวแปรresizeTimerเป็นตัวแปรทั่วโลกซึ่งหมายความว่าไม่มีการกำหนดwindowดังนั้นจึงเป็นเหมือนกับที่นี่เฉพาะตัวอย่างนี้จะดีกว่าเนื่องจากคุณไม่จำเป็นต้องกำหนดตัวแปรภายนอก และมันก็สมเหตุสมผลที่จะเพิ่มตัวแปรนี้ลงในwindowวัตถุเนื่องจากนั่นคือวัตถุที่ผู้ฟังเหตุการณ์ถูกผูกไว้
vsync

1
ขอบคุณ! ต้องการเพิ่มในบางกรณีจำเป็นต้องใช้ช่วงเวลาที่นานขึ้นเพื่อดำเนินการบางอย่างในการติดต่อกลับ เช่นในกรณีของฉัน 250 ไม่ทำงาน แต่ 700 ทำงานได้ดี
Maria Blair

ทางออกที่ดีที่สุด
Daniel Dewhurst

36

Internet Explorer จัดให้มีเหตุการณ์resizeEnd เบราว์เซอร์อื่น ๆ จะเรียกการปรับขนาดเหตุการณ์หลายครั้งในขณะที่คุณกำลังปรับขนาด

มีคำตอบที่ดีอื่น ๆ ที่นี่ที่แสดงวิธีการใช้ setTimeout และมี.throttle ,วิธีการเด้งกลับจาก lodash และขีดล่างดังนั้นฉันจะพูดถึงปลั๊กอิน jQueryของ Ben Alman ที่ทำการเค้นผลสำเร็จซึ่งทำสิ่งที่คุณต้องการ

สมมติว่าคุณมีฟังก์ชั่นนี้ที่คุณต้องการที่จะทริกเกอร์หลังจากปรับขนาด:

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

ตัวอย่าง Throttle
ในตัวอย่างต่อไปนี้onResize()จะถูกเรียกเพียงหนึ่งครั้งทุก ๆ 250 มิลลิวินาทีในระหว่างการปรับขนาดหน้าต่าง

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

ตัวอย่าง Debounce
ในตัวอย่างต่อไปนี้onResize()จะถูกเรียกเพียงครั้งเดียวเมื่อสิ้นสุดการดำเนินการปรับขนาดหน้าต่าง สิ่งนี้บรรลุผลเช่นเดียวกับที่ @Mark นำเสนอในคำตอบของเขา

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

1
Lodash ยังมีประโยชน์ที่นี่ซึ่งมีวิธี _.throttle และ _.debounce ด้วยเช่นกัน ฉันคิดว่า debounce เป็นวิธีการที่เหนือกว่าเมื่อเทียบกับตัวอย่างที่ยอมรับข้างต้น
เควินเลียรี

1
ใช่คำตอบนี้เขียนเมื่อ 5 ปีที่แล้ว มีสิ่งต่าง ๆ มากมายเกิดขึ้นนับตั้งแต่ปลั๊กอิน jQuery นี่คือฟังก์ชั่น debounce แบบสแตนด์อโลนด้วยdavidwalsh.name/javascript-debounce-function
jessegavin

26

มีทางออกที่สวยงามโดยใช้Underscore.jsดังนั้นหากคุณกำลังใช้ในโครงการของคุณคุณสามารถทำดังต่อไปนี้ -

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

นี่น่าจะพอ :) แต่ถ้าคุณสนใจที่จะอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้คุณสามารถตรวจสอบโพสต์บล็อกของฉัน - http://rifatnabi.com/post/detect-end-of-jquery-resize-event-using-underscore -debounce (deadlink)


1
เพียงแค่ต้องการที่จะเพิ่มที่lodashยังให้นี้
vsync

10

ทางออกหนึ่งคือการขยาย 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);


7

คุณสามารถเก็บรหัสอ้างอิงไปยัง setInterval ใด ๆ หรือ setTimeout แบบนี้:

var loop = setInterval(func, 30);

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

ในการทำเช่นนี้โดยไม่มีตัวแปร "ทั่วโลก" คุณสามารถเพิ่มตัวแปรท้องถิ่นลงในฟังก์ชันได้ Ex:

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

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

4

คุณสามารถใช้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 on(& bind) -event-handler มันแนบฟังก์ชั่นจัดการเหตุการณ์สำหรับหนึ่งหรือมากกว่าหนึ่งเหตุการณ์ไปยังองค์ประกอบที่เลือกถ้าเหตุการณ์ไม่ได้ถูกเรียกสำหรับช่วงเวลาที่กำหนด สิ่งนี้มีประโยชน์หากคุณต้องการเริ่มการติดต่อกลับหลังจากล่าช้าเช่นเหตุการณ์การปรับขนาดหรืออื่น ๆ https://github.com/yckart/jquery.unevent.js

;(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เหตุการณ์ยกเว้นว่าคุณสามารถส่งพารามิเตอร์พิเศษเป็นครั้งสุดท้ายได้:

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

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


3

มีวิธีที่ง่ายกว่ามากในการเรียกใช้ฟังก์ชั่นที่ส่วนท้ายของการปรับขนาดกว่าการคำนวณเวลาเดลต้าระหว่างการโทรสองครั้งเพียงทำแบบนี้:

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

สำหรับวิธีเชิงมุมใช้() => { }สัญกรณ์ในsetTimeoutเพื่อรักษาขอบเขตมิฉะนั้นคุณจะไม่สามารถเรียกใช้ฟังก์ชันหรือใช้งานthisได้


2

นี่คือการปรับเปลี่ยนรหัสของ Dolan ด้านบนฉันได้เพิ่มคุณสมบัติที่ตรวจสอบขนาดหน้าต่างในช่วงเริ่มต้นของการปรับขนาดและเปรียบเทียบกับขนาดเมื่อสิ้นสุดการปรับขนาดถ้าขนาดใหญ่กว่าหรือเล็กกว่าระยะขอบ ( เช่น 1,000) จากนั้นโหลดใหม่

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

2

คำตอบของ Mark Coleman นั้นดีกว่าคำตอบที่เลือก แต่ถ้าคุณต้องการหลีกเลี่ยงตัวแปรส่วนกลางสำหรับ timeout ID ( doitตัวแปรในคำตอบของ Mark) คุณสามารถทำอย่างใดอย่างหนึ่งต่อไปนี้:

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

ตัวเลือกที่ 2 ใช้อาร์กิวเมนต์.calleeจะไม่ทำงานหากฟังก์ชัน transpiled จาก ES6
Martin Burch

1

ฉันเขียนฟังก์ชัน wrapper litte ด้วยตัวเอง ...

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

1
(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(){
    //...
});

1

เท่าที่ตัวจัดการหน้าต่างเกี่ยวข้องเหตุการณ์การปรับขนาดแต่ละครั้งนั้นเป็นข้อความของตัวเองโดยมีจุดเริ่มต้นและจุดสิ้นสุดที่แตกต่างกันดังนั้นในทางเทคนิคทุกครั้งที่มีการปรับขนาดหน้าต่างมันคือจุดจบ

ต้องบอกว่าคุณอาจต้องการชะลอความต่อเนื่องของคุณ? นี่คือตัวอย่าง

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

1

นี่คือสคริปต์ที่ง่ายมากที่จะทริกเกอร์ทั้งเหตุการณ์ 'resizestart' และ 'resizeend' บนวัตถุหน้าต่าง

ไม่จำเป็นต้องยุ่งกับวันที่และเวลา

dตัวแปรหมายถึงจำนวนมิลลิวินาทีระหว่างเหตุการณ์การปรับขนาดก่อนวิกฤติเหตุการณ์สิ้นสุดการปรับขนาดที่คุณสามารถเล่นกับนี้เพื่อเปลี่ยนวิธีการที่สำคัญเหตุการณ์ที่ได้คือ

หากต้องการฟังกิจกรรมเหล่านี้สิ่งที่คุณต้องทำคือ:

resizestart: $(window).on('resizestart', function(event){console.log('Resize Start!');});

resizeend: $(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));

1
ฉันต้องการจุดเริ่มต้นและจุดสิ้นสุดของการปรับขนาดและดูเหมือนว่าจะทำงานได้ดี (ทดสอบใน Chrome, FF, Opera และ IE11) สำหรับการทดสอบฉันสร้าง JSFiddle ด้วยโซลูชันของคุณ: jsfiddle.net/8fsn2joj
Keith DC

1

นี่คือสิ่งที่ฉันใช้สำหรับการชะลอการกระทำซ้ำ ๆ มันสามารถเรียกได้หลายแห่งในรหัสของคุณ:

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

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" ซึ่งหลังจาก 500ms (หรือการตั้งค่าของคุณ) ได้รับขนาดหน้าต่างปัจจุบันและเปรียบเทียบต้นฉบับกับปัจจุบันหากไม่เหมือนกันหน้าต่างจะยังคงปรับขนาดใหม่ อย่าลืมที่จะลบข้อความคอนโซลในการผลิตและ (ไม่จำเป็น) สามารถทำให้การดำเนินการด้วยตนเอง "setFn"


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

สิ่งนี้ใช้ได้กับสิ่งที่ฉันพยายามทำในโครเมี่ยม สิ่งนี้จะไม่ดำเนินการเรียกกลับจนกว่า 200ms หลังจากปรับขนาดเหตุการณ์ล่าสุด


0

UPDATE!

ทางเลือกที่ดีกว่าสร้างโดยฉันอยู่ที่นี่: 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!
*/

คุณช่วยอธิบายการใช้งานที่นี่ได้ไหม คุณจะบอกใคร: $(window).resize(function() { delay_exec('test1', 30, function() { ... delayed stuff here ... }); });? รหัสสวยสะอาดเป็นอย่างอื่น ขอบคุณสำหรับการแบ่งปัน. :)
mhulse

คุณร็อค! ขอบคุณ @ Déján! +1 ตลอดทาง ตัวอย่างโค้ดเท่ ๆ มันใช้งานได้ดีมากจากสิ่งที่ฉันทดสอบ ใช้งานง่ายเกินไป ขอขอบคุณอีกครั้งสำหรับการแบ่งปัน :)
mhulse

0

ResizeStartและResizeEndกิจกรรมสำหรับหน้าต่าง

http://jsfiddle.net/04fLy8t4/

ฉันใช้งานฟังก์ชั่นที่กระตุ้นเหตุการณ์สองเหตุการณ์ในองค์ประกอบ DOM ผู้ใช้:

  1. resizestart
  2. resizeend

รหัส:

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

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

ฉันเขียนฟังก์ชั่นที่ส่งผ่านฟังก์ชั่นเมื่อห่อในเหตุการณ์ปรับขนาดใด ๆ มันใช้ช่วงเวลาเพื่อให้การปรับขนาดแม้ไม่ได้สร้างเหตุการณ์หมดเวลาอย่างต่อเนื่อง สิ่งนี้ช่วยให้สามารถดำเนินการอย่างอิสระจากเหตุการณ์การปรับขนาดอื่นนอกเหนือจากรายการบันทึกที่ควรลบออกในการผลิต

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

            }

}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.