2012-02-04 14 views
89

इस के साथ ठीक है बंद हो जाता है जब ..jQuery स्क्रॉल() का पता लगाने के उपयोगकर्ता स्क्रॉल

$(window).scroll(function() 
{ 
    $('.slides_layover').removeClass('showing_layover'); 
    $('#slides_effect').show(); 
}); 

मैं बता सकता है जब कोई मुझे क्या समझ से स्क्रॉल कर रहा है। तो इसके साथ में मैं यह पता लगाने की कोशिश कर रहा हूं कि किसी ने रुकने के दौरान कैसे पकड़ लिया है। उपर्युक्त उदाहरण से आप देख सकते हैं कि स्क्रॉलिंग होने पर मैं तत्वों के एक सेट से कक्षा को हटा रहा हूं। हालांकि, जब मैं स्क्रॉलिंग रोकता हूं तो मैं उस वर्ग को वापस रखना चाहता हूं।

इसका कारण यह है कि मैं एक लेओवर शो रखने का इरादा रखता हूं, जबकि पृष्ठ पृष्ठ को एक विशेष प्रभाव देने के लिए स्क्रॉल कर रहा है, जिस पर मैं काम करने का प्रयास कर रहा हूं। लेकिन एक वर्ग जिसे मैं उस प्रभाव के साथ संघर्ष को स्क्रॉल करते समय हटाने की कोशिश कर रहा हूं क्योंकि यह कुछ प्रकृति के पारदर्शिता प्रभाव के रूप में है।

+1

के संभावित डुप्लिकेट जाँच (http://stackoverflow.com/questions/8931605/fire-event-after-scrollling कृपया -स्क्रॉलबार-या-मूसहेल-जावास्क्रिप्ट) –

+0

बहुत बढ़िया, बिल्कुल नकल नहीं बल्कि निश्चित रूप से जो मैं ढूंढ रहा था उसकी गली को ऊपर उठाया और अंत में मेरी समस्या को हल करने में मेरी मदद की। धन्यवाद। – chris

उत्तर

211
$(window).scroll(function() { 
    clearTimeout($.data(this, 'scrollTimer')); 
    $.data(this, 'scrollTimer', setTimeout(function() { 
     // do something 
     console.log("Haven't scrolled in 250ms!"); 
    }, 250)); 
}); 

अद्यतन

मैं jQuery के डिफ़ॉल्ट on -event-हैंडलर को बढ़ाने के लिए एक विस्तार लिखा था। यह चयनित तत्वों में एक या अधिक घटनाओं के लिए एक ईवेंट हैंडलर फ़ंक्शन को जोड़ता है और यदि किसी दिए गए अंतराल के लिए ईवेंट ट्रिगर नहीं किया गया है तो हैंडलर फ़ंक्शन को कॉल करता है। यह उपयोगी है अगर आप विलंब के बाद केवल कॉलबैक को आग लगाना चाहते हैं, जैसे आकार बदलने की घटना, या ऐसे।

अपडेट के लिए github-repo जांचना महत्वपूर्ण है!

https://github.com/yckart/jquery.unevent.js

;(function ($) { 
    var on = $.fn.on, timer; 
    $.fn.on = function() { 
     var args = Array.apply(null, arguments); 
     var last = args[args.length - 1]; 

     if (isNaN(last) || (last === 1 && args.pop())) return on.apply(this, args); 

     var delay = args.pop(); 
     var fn = args.pop(); 

     args.push(function() { 
      var self = this, params = arguments; 
      clearTimeout(timer); 
      timer = setTimeout(function() { 
       fn.apply(self, params); 
      }, delay); 
     }); 

     return on.apply(this, args); 
    }; 
}(this.jQuery || this.Zepto)); 

किसी अन्य on या bind -event हैंडलर है जैसे कि यह प्रयोग करें, सिवाय इसके कि आप पिछले के रूप में एक अतिरिक्त पैरामीटर पारित कर सकते हैं:

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

http://yckart.github.com/jquery.unevent.js/

(यह डेमो 012 के बजाय resize का उपयोग करता है, लेकिन कौन परवाह करता है ?!) आरंभ और अंत क्षमता

+0

यह अभी भी 100% सटीक नहीं है: कभी-कभी उपयोगकर्ता 250 एमएस –

+0

के बाद भी स्क्रॉलिंग को रोकता है और फिर से शुरू करता है यह कोड बहुत अच्छा काम करता है, लेकिन यह पूरी तरह से jquery ui के स्वतः पूर्ण विजेट को तोड़ देता है। – kkazakov

+0

@ArmanBimatov तब इसे माना जाएगा क्योंकि उपयोगकर्ता स्क्रॉलिंग रखता है, जो अच्छा लगता है, नहीं? – godblessstrawberry

3

आप एक अंतराल है कि हर 500 एमएस या तो चलाता है, निम्नलिखित की तर्ज पर सेट कर सकते हैं:

var curOffset, oldOffset; 
oldOffset = $(window).scrollTop(); 
var $el = $('.slides_layover'); // cache jquery ref 
setInterval(function() { 
    curOffset = $(window).scrollTop(); 
    if(curOffset != oldOffset) { 
    // they're scrolling, remove your class here if it exists 
    if($el.hasClass('showing_layover')) $el.removeClass('showing_layover'); 
    } else { 
    // they've stopped, add the class if it doesn't exist 
    if(!$el.hasClass('showing_layover')) $el.addClass('showing_layover'); 
    } 
    oldOffset = curOffset; 
}, 500); 

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

44

jQuery थ्रोटल/debounce

jQuery debounce का उपयोग करते हुए इस तरह की समस्याओं के लिए एक अच्छा एक है। jsFidlle

$(window).scroll($.debounce(250, true, function(){ 
    $('#scrollMsg').html('SCROLLING!'); 
})); 
$(window).scroll($.debounce(250, function(){ 
    $('#scrollMsg').html('DONE!'); 
})); 

दूसरा पैरामीटर "at_begin" ध्वज है। यहां मैंने दिखाया है कि "स्क्रॉल स्टार्ट" और "स्क्रॉल फिनिश" दोनों में कोड कैसे निष्पादित किया जाए।

Lodash

बैरी पी, jsFiddle, underscore या lodash द्वारा सुझाव दिया गया है का उपयोग करना भी एक debounce, थोड़ा अलग API के साथ प्रत्येक की है।

$(window).scroll(_.debounce(function(){ 
    $('#scrollMsg').html('SCROLLING!'); 
}, 150, { 'leading': true, 'trailing': false })); 

$(window).scroll(_.debounce(function(){ 
    $('#scrollMsg').html('STOPPED!'); 
}, 150)); 
+0

क्या एक ही समय में एक सामान्य स्क्रॉल फ़ंक्शन का उपयोग करना संभव है? $ (विंडो) .scroll (function() {...}); –

+0

बेशक, jQuery एक ईवेंट में कई हैंडलर को बाध्य करेगा जैसा आप चाहें। – Sinetheta

+3

यहां इसका एक लो-डैश संस्करण है: http://jsfiddle.net/barrypeterson/zzghqk62/ –

8

रॉब डब्ल्यू ने श्वास पर एक और पोस्ट की जांच की जो कि मेरे मूल रूप से एक समान पोस्ट था। कौन सा है कि के माध्यम से पढ़ने मैं एक साइट के लिए एक लिंक मिल गया:

http://james.padolsey.com/javascript/special-scroll-events-for-jquery/

यह वास्तव में मेरे अपने की जरूरत के लिए एक छोटे से फेरबदल के बाद बहुत अच्छी तरह से मेरी समस्या का समाधान की मदद करने के समाप्त हो गया है, लेकिन सब कुछ खत्म मदद की बक का एक बहुत मिलता है रास्ते से बाहर और मुझे अपने आप को बाहर निकालने के बारे में 4 घंटे बचाया।

इस पोस्ट के रूप में देखकर कुछ योग्यता प्रतीत होती है, मुझे लगा कि मैं वापस आऊंगा और मूल रूप से उल्लिखित लिंक पर कोड प्रदान करूंगा, अगर लेखक ने कभी साइट के साथ एक अलग दिशा तय करने का फैसला किया और समाप्त हो गया लिंक नीचे।

(function(){ 

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

    special.scrollstart = { 
     setup: function() { 

      var timer, 
       handler = function(evt) { 

        var _self = this, 
         _args = arguments; 

        if (timer) { 
         clearTimeout(timer); 
        } else { 
         evt.type = 'scrollstart'; 
         jQuery.event.handle.apply(_self, _args); 
        } 

        timer = setTimeout(function(){ 
         timer = null; 
        }, special.scrollstop.latency); 

       }; 

      jQuery(this).bind('scroll', handler).data(uid1, handler); 

     }, 
     teardown: function(){ 
      jQuery(this).unbind('scroll', jQuery(this).data(uid1)); 
     } 
    }; 

    special.scrollstop = { 
     latency: 300, 
     setup: function() { 

      var timer, 
        handler = function(evt) { 

        var _self = this, 
         _args = arguments; 

        if (timer) { 
         clearTimeout(timer); 
        } 

        timer = setTimeout(function(){ 

         timer = null; 
         evt.type = 'scrollstop'; 
         jQuery.event.handle.apply(_self, _args); 

        }, special.scrollstop.latency); 

       }; 

      jQuery(this).bind('scroll', handler).data(uid2, handler); 

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

})(); 
2
function scrolled() { 
    //do by scroll start 
    $(this).off('scroll')[0].setTimeout(function(){ 
     //do by scroll end 
     $(this).on('scroll',scrolled); 
    }, 500) 
} 
$(window).on('scroll',scrolled); 

बहुत छोटा संस्करण काफी सटीक है कि जब ट्रिगर किया जाएगा नहीं था जब आप स्क्रॉलिंग रोकते हैं तो आप लंबे समय तक स्क्रॉल बार को आगे बढ़ना बंद कर देते हैं। मुझे लगता है कि एक बेहतर समाधान जैसे ही वे स्क्रॉल शुरू माउस (mouseup) के उपयोगकर्ता जाने दे के लिए सुनने के लिए है:

$(window).scroll(function(){ 
    $('#scrollMsg').html('SCROLLING!'); 
    var stopListener = $(window).mouseup(function(){ // listen to mouse up 
     $('#scrollMsg').html('STOPPED SCROLLING!'); 
     stopListner(); // Stop listening to mouse up after heard for the first time 
    }); 
}); 

और यह काम कर रहा this JSFiddle

4

मैं एक समय समाप्ति के लिए कि सुनने के ऊपर टिप्पणी से कुछ के साथ सहमति के साथ

+2

यह बहुत अच्छा लगता है, लेकिन यदि आप ट्रैकपैड पर 2-उंगली इशारा करते हुए स्क्रॉल कर रहे हैं, या स्क्रोलव्हील हैं, तो माउसअप को निकाल दिया नहीं जाता है। यह शायद स्क्रॉल करने का सबसे आम तरीका है, जो इसे समस्याग्रस्त बनाता है। – Adam

+1

अच्छा बिंदु। लेकिन संभावित रूप से इसके लिए कुछ फिक्स हैं। Jquery के 'mousewheel' ईवेंट का उपयोग करना या पहले mousedown पर ट्रैक रखना, और दूसरों द्वारा सुझाए गए टाइमआउट दृष्टिकोण का उपयोग करना। लेकिन मुझे लगता है कि माउस व्हील इवेंट्स के लिए अन्य उत्तरों के संयोजन का उपयोग करके और स्क्रॉल बार ड्रैगिंग के लिए यह जवाब सबसे सटीक परिणाम – Theo

1

में देखा जा सकता का एक उदाहरण यह ठीक है ऐसा कुछ है जिसे मैंने पहले उपयोग किया है। असल में आप पिछले scrollTop() पर एक रेफरी देखते हैं। एक बार आपका टाइमआउट साफ़ हो जाने पर, आप वर्तमान scrollTop() देखें और यदि वे समान हैं, तो आप स्क्रॉलिंग कर रहे हैं।

$(window).scroll((e) -> 
    clearTimeout(scrollTimer) 
    $('header').addClass('hidden') 

    scrollTimer = setTimeout((() -> 
    if $(this).scrollTop() is currentScrollTop 
     $('header').removeClass('hidden') 
), animationDuration) 

    currentScrollTop = $(this).scrollTop() 
) 
0

[स्क्रॉलबार scrollling के बाद आग घटना या जावास्क्रिप्ट माउसव्हील] jquery mobile scrollstop event

$(document).on("scrollstop",function(){ 
    alert("Stopped scrolling!"); 
}); 
+3

करेगा जो jquery मोबाइल, jquery नहीं है। मैं लगभग उसी जाल के लिए गिर गया;) – katzenhut

संबंधित मुद्दे