जावास्क्रिप्ट / JQuery: $ (खिड़की)। आकार में बताएं कि आग को कैसे पूरा किया जाए?


235

मैं JQuery का उपयोग कर रहा हूँ जैसे:

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

हालाँकि, ऐसा प्रतीत होता है कि यदि व्यक्ति मैन्युअल रूप से अपने ब्राउज़र की विंडो को बड़ा / छोटा करने के लिए विंडो किनारे को खींचकर आकार देता है, तो .resizeऊपर की घटना कई बार आग लग जाती है।

प्रश्न: मैं एक फ़ंक्शन को कैसे कॉल कर सकता हूं, जब ब्राउज़र विंडो आकार पूरा हो जाए (ताकि घटना केवल एक बार आग लगे)?


इस उत्तर को देखें: stackoverflow.com/questions/667426/… इसमें आपके फ़ंक्शन के निष्पादन में देरी करने के लिए टाइमआउट का उपयोग शामिल है।
एलेस्टेयर पिट्स

मुझे नहीं पता कि अगर यह संभव है, तो आप इस प्लगइन की कोशिश कर सकते हैं, हालांकि benalman.com/projects/jquery-resize-plugin
BrunoLM

वैसे, मैंने देखा कि यह मोबाइल ब्राउज़रों में बहुत उपयोगी है जो उपयोगकर्ता के स्क्रॉल करते समय धीरे-धीरे एड्रेस बार को छिपाने की प्रवृत्ति रखते हैं, इसलिए स्क्रीन को आकार देते हैं। मुझे यह भी उम्मीद थी कि स्क्रीन केवल डेस्कटॉप पर ही
बनेगी

जवाबों:


299

यहां CMS के समाधान का एक संशोधन है जिसे आपके कोड में कई स्थानों पर कॉल किया जा सकता है:

var waitForFinalEvent = (function () {
  var timers = {};
  return function (callback, ms, uniqueId) {
    if (!uniqueId) {
      uniqueId = "Don't call this twice without a uniqueId";
    }
    if (timers[uniqueId]) {
      clearTimeout (timers[uniqueId]);
    }
    timers[uniqueId] = setTimeout(callback, ms);
  };
})();

उपयोग:

$(window).resize(function () {
    waitForFinalEvent(function(){
      alert('Resize...');
      //...
    }, 500, "some unique string");
});

यदि आप केवल एक बार कॉल करते हैं तो CMS का समाधान ठीक है, लेकिन यदि आप इसे कई बार कहते हैं, उदाहरण के लिए, यदि आपके कोड के अलग-अलग हिस्सों ने विंडो आकार बदलने के लिए अलग-अलग कॉलबैक सेट किए हैं, तो यह b / c विफल हो जाएगा, क्योंकि वे timerचर साझा करते हैं।

इस संशोधन के साथ, आप प्रत्येक कॉलबैक के लिए एक अद्वितीय आईडी की आपूर्ति करते हैं, और उन अद्वितीय आईडी का उपयोग सभी टाइमआउट घटनाओं को अलग रखने के लिए किया जाता है।


2
I <3 u, मैंने इसे फुलस्क्रीन (गैर html5) हाईचर्ट्स ग्राफ और शानदार काम करते हुए संयुक्त किया।
माइकल जे। कैलकिंस

बिलकुल अविश्वसनीय!
स्टार्कर्स

2
चूँकि मुझे आपके उत्तर से इतना लाभ हुआ है, तो मुझे लगा कि मैंने समुदाय के बाकी हिस्सों के लिए आपके प्रदान किए गए कोड का एक कार्यशील प्रोटोटाइप साझा किया है: jsfiddle.net/h6h2pzpu/3 । सभी का आनंद लें!
जोनास स्टॉस्की

1
यह सब सही है, लेकिन यह वास्तविक कार्य के निष्पादन को विलंबित (एमएस) की मात्रा से विलुप्त कर देता है, जो बहुत कम हो सकता है।
टॉमस एम।

यह सिर्फ यह करता है कि यह अंतिम आकार बदलने और उन मिलीसेकंड पर रिले न करने का एक तरीका है? वैसे भी यह मेरा दिन बचा: ') धन्यवाद।
सिंह

138

मैं एक ईवेंट बनाना पसंद करता हूं:

$(window).bind('resizeEnd', function() {
    //do something, window hasn't changed size in 500ms
});

यहां बताया गया है कि आप इसे कैसे बनाते हैं:

 $(window).resize(function() {
        if(this.resizeTO) clearTimeout(this.resizeTO);
        this.resizeTO = setTimeout(function() {
            $(this).trigger('resizeEnd');
        }, 500);
    });

आप इसे वैश्विक जावास्क्रिप्ट फ़ाइल में कहीं रख सकते हैं।


मैंने इस समाधान का उपयोग किया। लेकिन लंबे समय में मैं ब्राहण के समाधान को लागू करना चाहूंगा।
भारत पाटील

यह आपको केवल एक समारोह में ही नहीं, बल्कि एक ही समारोह में, उस स्थान पर सभी घटनाओं के लिए बाध्य करने की अनुमति देता है। आपके पास कई पृष्ठ हैं।। js फाइलें अलग-अलग प्रतिक्रियाओं की आवश्यकता होती हैं
हांज़ोलो

यह मेरे लिए काम नहीं किया, लेकिन DusanV उत्तर ने काम किया
lightbyte

123

मैं बार-बार कार्रवाई में देरी के लिए निम्नलिखित फ़ंक्शन का उपयोग करता हूं, यह आपके मामले के लिए काम करेगा:

var delay = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  };
})();

उपयोग:

$(window).resize(function() {
    delay(function(){
      alert('Resize...');
      //...
    }, 500);
});

कॉलबैक फ़ंक्शन इसके पास गया, केवल तभी निष्पादित होगा जब विलंब के लिए अंतिम कॉल निर्दिष्ट समय के बाद की गई हो, अन्यथा एक टाइमर रीसेट हो जाएगा, मुझे यह अन्य उद्देश्यों के लिए उपयोगी लगता है जैसे कि जब उपयोगकर्ता ने टाइप करना बंद कर दिया, आदि। ..


5
मुझे लगता है कि यह दृष्टिकोण विफल हो सकता है यदि कई बार उपयोग किया जाता है (जैसे कि कोड सेटअप कॉलबैक के विभिन्न भागों को $(window).resize) तो वे सभी timerचर साझा करेंगे । प्रस्तावित समाधान के लिए नीचे मेरा जवाब देखें।
ब्राह्मण २ bra

बहुत अच्छा! एक जादू की तरह काम करता है! आपके उत्तरों की तरह ... सरल और सुरुचिपूर्ण!
श्री कद्दू

74

यदि आपके पास अंडरस्कोर .js स्थापित है, तो आप निम्न कर सकते हैं:

$(window).resize(_.debounce(function(){
    alert("Resized");
},500));

1
यहां तक ​​कि अगर आप अंडरस्कोर को शामिल नहीं करना चाहते हैं, तो कम से कम इसके लिए स्रोत को पकड़ो: underscorejs.org/docs/underscore.html#section-67
tybro0103

डेब्यू यहाँ सही तकनीक है, यह सिर्फ कार्यान्वयन की बात है। और यह बेहतर कार्यान्वयन है यदि अंडरस्कोर / लॉडश पहले से ही एक परियोजना निर्भरता है।
फैक्टर मिस्टिक

यह अब मैं उपयोग कर रहा हूँ,
भारत पाटील

20

पहले बताए गए कुछ समाधान मेरे काम नहीं आए, भले ही वे अधिक सामान्य उपयोग के हों। वैकल्पिक रूप से मुझे यह मिल गया है जिसने खिड़की के आकार पर काम किया है:

$(window).bind('resize', function(e){
    window.resizeEvt;
    $(window).resize(function(){
        clearTimeout(window.resizeEvt);
        window.resizeEvt = setTimeout(function(){
        //code to do after window is resized
        }, 250);
    });
});

1
केवल आपके उदाहरण ने मेरे लिए काम किया ... ऊपर के अन्य लोगों ने नहीं किया! मुझे यकीन नहीं है कि आपका जवाब क्यों नहीं चुना गया।
मुम्बो जंबो

मुझे समझ में नहीं आता कि रिसाइज़ इवेंट के अंदर रिसाइज़ इवेंट को क्यों पकड़ना है, लेकिन यह मेरे लिए भी काम करता है ...
lightbyte

मुंबो जंबो, मुझे लगता है क्योंकि अन्य सामान्यीकरण पर ध्यान केंद्रित करते हैं, ऐसे किसी भी मुद्दे (किसी फ़ंक्शन के कई कॉल) के समाधान की तलाश में हैं।
DusanV

lightbyte, ऐसा इसलिए है क्योंकि आपको पिछली घटनाओं को हर बार फ़ंक्शन को रोकना होगा।
दसनव

13

डेविड वॉल्श के लिए बहुत धन्यवाद, यहाँ अंडरस्कोर डिब्यू का एक वैनिला संस्करण है।

कोड:

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
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);
    };
};

सरल उपयोग:

var myEfficientFn = debounce(function() {
    // All the taxing stuff you do
}, 250);

$(window).on('resize', myEfficientFn);

Ref: http://davidwalsh.name/javascript-debounce-function


6

वास्तव में, जैसा कि मैं जानता हूं, आप आकार बदलने के तुरंत बाद कुछ कार्य नहीं कर सकते, केवल इसलिए कि आप भविष्य के उपयोगकर्ता के कार्यों को नहीं जानते हैं। लेकिन आप मान सकते हैं कि दो आकार बदलने वाली घटनाओं के बीच का समय बीत चुका है, इसलिए यदि आप इस समय से थोड़ा अधिक इंतजार करते हैं और कोई आकार परिवर्तन नहीं किया जाता है, तो आप अपने कार्य को कॉल कर सकते हैं।
विचार यह है कि हम इसका उपयोग करते हैं setTimeoutऔर इसे बचाने या हटाने के लिए आईडी है। उदाहरण के लिए, हम जानते हैं कि दो आकार बदलने वाली घटनाओं के बीच का समय 500ms है, इसलिए हम 750ms का इंतजार करेंगे।

var a;
$(window).resize(function(){
  clearTimeout(a);
  a = setTimeout(function(){
    // call your function
  },750);
});


3

विश्व स्तर पर विलंबित श्रोता घोषित करें:

var resize_timeout;

$(window).on('resize orientationchange', function(){
    clearTimeout(resize_timeout);

    resize_timeout = setTimeout(function(){
        $(window).trigger('resized');
    }, 250);
});

और नीचे श्रोताओं को resizedघटना के रूप में उपयोग करना चाहते हैं:

$(window).on('resized', function(){
    console.log('resized');
});

धन्यवाद, यह वर्तमान में सबसे अच्छा समाधान है। इसके अलावा मैंने परीक्षण किया है कि विंडो को आकार देते समय 250ms सबसे अच्छा तरीका है।
एलेक्सियोवे

3

इससे मेरा काम बनता है। इस समाधान को देखें - https://alvarotrigo.com/blog/firing-resize-event-only-once-when-resizing-is-finished/

var resizeId;
$(window).resize(function() {
    clearTimeout(resizeId);
    resizeId = setTimeout(doneResizing, 500);
});
function doneResizing(){
    //whatever we want to do 
}


2

विलंबित विंडो आकार परिवर्तन के लिए सरल jQuery प्लगइन।

वाक्य - विन्यास:

घटना का आकार बदलने के लिए नया फ़ंक्शन जोड़ें

jQuery(window).resizeDelayed( func, delay, id ); // delay and id are optional

पहले जोड़ा गया फ़ंक्शन (इसकी आईडी घोषित करके) निकालें

jQuery(window).resizeDelayed( false, id );

सभी कार्यों को निकालें

jQuery(window).resizeDelayed( false );

उपयोग:

// ADD SOME FUNCTIONS TO RESIZE EVENT
jQuery(window).resizeDelayed( function(){ console.log( 'first event - should run after 0.4 seconds'); }, 400,  'id-first-event' );
jQuery(window).resizeDelayed( function(){ console.log('second event - should run after 1.5 seconds'); }, 1500, 'id-second-event' );
jQuery(window).resizeDelayed( function(){ console.log( 'third event - should run after 3.0 seconds'); }, 3000, 'id-third-event' );

// LETS DELETE THE SECOND ONE
jQuery(window).resizeDelayed( false, 'id-second-event' );

// LETS ADD ONE WITH AUTOGENERATED ID(THIS COULDNT BE DELETED LATER) AND DEFAULT TIMEOUT (500ms)
jQuery(window).resizeDelayed( function(){ console.log('newest event - should run after 0.5 second'); } );

// LETS CALL RESIZE EVENT MANUALLY MULTIPLE TIMES (OR YOU CAN RESIZE YOUR BROWSER WINDOW) TO SEE WHAT WILL HAPPEN
jQuery(window).resize().resize().resize().resize().resize().resize().resize();

उपयोग की स्थिति:

first event - should run after 0.4 seconds
newest event - should run after 0.5 second
third event - should run after 3.0 seconds

लगाना:

jQuery.fn.resizeDelayed = (function(){

    // >>> THIS PART RUNS ONLY ONCE - RIGHT NOW

    var rd_funcs = [], rd_counter = 1, foreachResizeFunction = function( func ){ for( var index in rd_funcs ) { func(index); } };

    // REGISTER JQUERY RESIZE EVENT HANDLER
    jQuery(window).resize(function() {

        // SET/RESET TIMEOUT ON EACH REGISTERED FUNCTION
        foreachResizeFunction(function(index){

            // IF THIS FUNCTION IS MANUALLY DISABLED ( by calling jQuery(window).resizeDelayed(false, 'id') ),
            // THEN JUST CONTINUE TO NEXT ONE
            if( rd_funcs[index] === false )
                return; // CONTINUE;

            // IF setTimeout IS ALREADY SET, THAT MEANS THAT WE SHOULD RESET IT BECAUSE ITS CALLED BEFORE DURATION TIME EXPIRES
            if( rd_funcs[index].timeout !== false )
                clearTimeout( rd_funcs[index].timeout );

            // SET NEW TIMEOUT BY RESPECTING DURATION TIME
            rd_funcs[index].timeout = setTimeout( rd_funcs[index].func, rd_funcs[index].delay );

        });

    });

    // <<< THIS PART RUNS ONLY ONCE - RIGHT NOW

    // RETURN THE FUNCTION WHICH JQUERY SHOULD USE WHEN jQuery(window).resizeDelayed(...) IS CALLED
    return function( func_or_false, delay_or_id, id ){

        // FIRST PARAM SHOULD BE SET!
        if( typeof func_or_false == "undefined" ){

            console.log( 'jQuery(window).resizeDelayed(...) REQUIRES AT LEAST 1 PARAMETER!' );
            return this; // RETURN JQUERY OBJECT

        }

        // SHOULD WE DELETE THE EXISTING FUNCTION(S) INSTEAD OF CREATING A NEW ONE?
        if( func_or_false == false ){

            // DELETE ALL REGISTERED FUNCTIONS?
            if( typeof delay_or_id == "undefined" ){

                // CLEAR ALL setTimeout's FIRST
                foreachResizeFunction(function(index){

                    if( typeof rd_funcs[index] != "undefined" && rd_funcs[index].timeout !== false )
                        clearTimeout( rd_funcs[index].timeout );

                });

                rd_funcs = [];

                return this; // RETURN JQUERY OBJECT

            }
            // DELETE ONLY THE FUNCTION WITH SPECIFIC ID?
            else if( typeof rd_funcs[delay_or_id] != "undefined" ){

                // CLEAR setTimeout FIRST
                if( rd_funcs[delay_or_id].timeout !== false )
                    clearTimeout( rd_funcs[delay_or_id].timeout );

                rd_funcs[delay_or_id] = false;

                return this; // RETURN JQUERY OBJECT

            }

        }

        // NOW, FIRST PARAM MUST BE THE FUNCTION
        if( typeof func_or_false != "function" )
            return this; // RETURN JQUERY OBJECT

        // SET THE DEFAULT DELAY TIME IF ITS NOT ALREADY SET
        if( typeof delay_or_id == "undefined" || isNaN(delay_or_id) )
            delay_or_id = 500;

        // SET THE DEFAULT ID IF ITS NOT ALREADY SET
        if( typeof id == "undefined" )
            id = rd_counter;

        // ADD NEW FUNCTION TO RESIZE EVENT
        rd_funcs[id] = {
            func : func_or_false,
            delay: delay_or_id,
            timeout : false
        };

        rd_counter++;

        return this; // RETURN JQUERY OBJECT

    }

})();

1

यह मानते हुए कि माउस कर्सर को विंडो आकार बदलने के बाद दस्तावेज़ में वापस आ जाना चाहिए, हम ऑनमाउसओवर इवेंट के साथ कॉलबैक जैसा व्यवहार बना सकते हैं। यह मत भूलो कि यह समाधान उम्मीद के मुताबिक टच-सक्षम स्क्रीन के लिए काम नहीं कर सकता है।

var resizeTimer;
var resized = false;
$(window).resize(function() {
   clearTimeout(resizeTimer);
   resizeTimer = setTimeout(function() {
       if(!resized) {
           resized = true;
           $(document).mouseover(function() {
               resized = false;
               // do something here
               $(this).unbind("mouseover");
           })
       }
    }, 500);
});

माउस-आधारित डेस्कटॉप-ओनली साइट्स के लिए ठीक है, लेकिन माउसओवर इवेंट कभी नहीं होगा यदि, उदाहरण के लिए, उपयोगकर्ता मोबाइल पर है और परिदृश्य से पोर्ट्रेट तक बदलता है, या यदि उन्होंने टचस्क्रीन डेस्कटॉप पर विंडो का आकार बदला है।
user56reinstatemonica8

आप नवीनतम विंडो पर कीबोर्ड की मदद से ब्राउज़र विंडो को आकार दे सकते हैं जैसे विन-एरो-लेफ्ट विन-एरो-राईट-राइट इत्यादि ...
Lu4

0

यह वही है जो मैंने लागू किया है:

$ (विंडो) .resize (फ़ंक्शन () {setTimeout (someFunction, 500);});

हम कर सकते हैं setTimeout स्पष्ट अगर हम आकार की तुलना में कम होने की अपेक्षा500ms

शुभ लाभ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.