2011-08-12 29 views
54

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

$(document).scroll(function(){ 
    //who did this?! 
}); 

मुझे तीन प्रकार की स्थितियों को देखते हैं जो ब्राउज़र में स्क्रॉलिंग का कारण बनते हैं।

  1. उपयोगकर्ता कुछ कार्रवाई करता है। उदाहरण के लिए, मूसहेल, तीर कुंजी, पृष्ठ ऊपर/नीचे कुंजी, घर/अंत कुंजी का उपयोग करता है।
  2. ब्राउज़र स्वचालित रूप से स्क्रॉल करता है। उदाहरण के लिए, अपने ब्राउज़र में बैक बटन का उपयोग करते समय यह स्वचालित रूप से अंतिम ज्ञात स्क्रॉल स्थिति पर जायेगा।
  3. जावास्क्रिप्ट स्क्रॉल। उदाहरण के लिए, element.scrollTo(x,y)
+1

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

+0

मैंने बैक बटन के माध्यम से स्क्रॉलिंग को "ब्राउज़र स्क्रॉल" माना। कुछ और - मूसहेल, ऊपर/नीचे तीर, केंद्र बटन क्लिक, आदि उपयोगकर्ता स्क्रॉल होगा। मुझे लगता है कि मेरा असली सवाल हो सकता है - क्या कोई घटना अलग-अलग होने का कोई तरीका है? मैंने ईवेंट ऑब्जेक्ट पर गुणों को देखा, लेकिन कुछ भी नहीं मिला। तीन परिदृश्य जिन्हें मैं कल्पना कर सकता हूं ब्राउज़र ब्राउज़र स्क्रॉलिंग शुरू किया गया है, जावास्क्रिप्ट ने स्क्रॉलिंग शुरू की है और उपयोगकर्ता ने स्क्रॉलिंग शुरू की है। उम्मीद है कि चीजों को स्पष्ट बनाता है। – mrtsherman

+0

@mrtsherman मुझे एक ही आउटपुट प्राप्त करते समय इनमें से कुछ मिला: http://stackoverflow.com/questions/2834667/how-can-i-differentiate-a-manual-scroll-via-mousewheel-scrollbar-from- ए-जावस्क – AlphaMale

उत्तर

17

दुर्भाग्य से, यह कहने का कोई सीधा तरीका नहीं है।

मैं कहूंगा कि आप को अपने ऐप को फिर से डिजाइन कर सकते हैं ताकि यह इस प्रकार के प्रवाह पर निर्भर न हो, इसके लिए जाएं।

यदि नहीं, तो एक वैकल्पिक हल मैं के बारे में सोच सकते हैं उपयोगकर्ता द्वारा आरंभ किए स्क्रॉल का ट्रैक रखने और जाँच लें कि देखने के लिए कि पुस्तक ब्राउज़र द्वारा या उपयोगकर्ता द्वारा ट्रिगर किया गया है।

यहां एक उदाहरण दिया गया है कि मैंने एक साथ रखा है जो यह बहुत अच्छा करता है (ब्राउज़र को छोड़कर जहां jQuery इतिहास में समस्याएं हैं)।

आपको इसे पूरी तरह से परीक्षण करने में सक्षम होने के लिए स्थानीय रूप से चलाने की आवश्यकता है (जेएसफ़िल्ड/जेएसबीएन सामग्री के रूप में अच्छी तरह से फिट नहीं है)।userScroll पेज नीचे करने के लिए कूद करने के बन जाता है लिंक पर true

  • क्लिक करें - - userScroll का उपयोग कर माउस/कुंजीपटल false
  • स्क्रॉल है

    • पृष्ठ भार:

      यहाँ परीक्षण मामलों कि मैं मान्य है - userScrollfalse

    • वापस क्लिक करें/आगे - userScrollfalse बन जाता है;

    <!DOCTYPE html> 
    <html lang="en"> 
    <head> 
        <meta charset="utf-8" /> 
        <script src="http://code.jquery.com/jquery-1.6.1.min.js"></script> 
        <script type="text/javascript" src="https://raw.github.com/tkyk/jquery-history-plugin/master/jquery.history.js"></script> 
    </head> 
    <body> 
        <span> hello there </span><br/> 
        <a href="#bottom"> click here to go down </a> 
        <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
        <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
        <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
        <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
        <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
        <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
        <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
        <a name="bottom"> just sitting </a> 
    </body> 
    <script type="text/javascript"> 
    
    var userScroll = false;  
    
    function mouseEvent(e) { 
        userScroll = true; 
    } 
    
    
    $(function() { 
    
        // reset flag on back/forward 
        $.history.init(function(hash){ 
         userScroll = false; 
        }); 
    
        $(document).keydown(function(e) { 
         if(e.which == 33  // page up 
          || e.which == 34  // page dn 
          || e.which == 32  // spacebar 
          || e.which == 38  // up 
          || e.which == 40  // down 
          || (e.ctrlKey && e.which == 36)  // ctrl + home 
          || (e.ctrlKey && e.which == 35)  // ctrl + end 
         ) { 
          userScroll = true; 
         } 
        }); 
    
        // detect user scroll through mouse 
        // Mozilla/Webkit 
        if(window.addEventListener) { 
         document.addEventListener('DOMMouseScroll', mouseEvent, false); 
        } 
    
        //for IE/OPERA etc 
        document.onmousewheel = mouseEvent; 
    
    
        // to reset flag when named anchors are clicked 
        $('a[href*=#]').click(function() { 
         userScroll = false; 
        }); 
    
         // detect browser/user scroll 
        $(document).scroll(function(){ 
         console.log('Scroll initiated by ' + (userScroll == true ? "user" : "browser")); 
        }); 
    }); 
    </script> 
    </html> 
    

    नोट्स:

    • यह स्क्रॉल जब उपयोगकर्ता माउस के साथ स्क्रॉलबार खींच लेता है ट्रैक नहीं करता। इसे कुछ और कोड के साथ जोड़ा जा सकता है, जिसे मैंने आपके लिए व्यायाम के रूप में छोड़ा था।
    • event.keyCodes ओएस द्वारा भिन्न हो सकता है, इसलिए आपको इसे उचित रूप से बदलना पड़ सकता है।

    आशा है कि इससे मदद मिलती है!

  • +0

    धन्यवाद श्रीचिफ। मुझे लगता है कि यह सबसे अच्छा जवाब है, भले ही मैं उम्मीद नहीं कर रहा था कि यह क्या होगा (क्या? कोई घटना नहीं है। संपत्ति 'संपत्ति ?!)। – mrtsherman

    2

    इसके बजाय Mousewheel और DOMMouseScroll ईवेंट का उपयोग करने का प्रयास करें। http://www.quirksmode.org/dom/events/scroll.html

    +0

    इस सुझाव के लिए धन्यवाद। हालांकि मुझे नहीं लगता कि यह वही है जो मैं चाहता हूं। मुझे वास्तव में ब्राउज़र और उपयोगकर्ता स्क्रॉल के बीच अंतर करने की आवश्यकता है। सिर्फ मूसहेल को लक्षित न करें। – mrtsherman

    +0

    मुझे लगता है कि mousewheel घटना ऑनस्कोल घटना से पहले निकाल दिया गया है। तो आप mousewheel पर var userscroll = true सेट कर सकते हैं, और इसे ऑनस्क्रॉल में पहचान सकते हैं (और इसे गलत पर रीसेट करें)। – Gerben

    +2

    उपयोगकर्ता की बड़ी संख्या में स्क्रॉल ईवेंट शुरू किए गए हैं जिन्हें कवर नहीं किया जाएगा। तीर कुंजियां, खिड़की का आकार बदलना इत्यादि। यह कहना बेहद सुरक्षित है कि इस घटना के प्रेषक "एक्स" से कहें कि इस घटना के बाहर सबकुछ "एक्स" होना चाहिए। यह मेरे लिए भी काम नहीं करता है क्योंकि मैं ब्राउज़र द्वारा शुरू की गई स्क्रॉल की पहचान करना चाहता हूं, न कि उपयोगकर्ता द्वारा। तो इस प्रयोग के मामले को बनाने के लिए मुझे सभी मूसहेल स्क्रॉल को ट्रैक करना होगा और फिर यह निर्धारित करने का प्रयास करें कि बाद की स्क्रॉल घटना उस पर आधारित उपयोगकर्ता थी या नहीं। मुझे डर है कि यह सिर्फ काम नहीं कर रहा है। – mrtsherman

    6

    जहां तक ​​मुझे पता है कि यह "उपयोगकर्ता" या अन्य माध्यमों द्वारा स्क्रॉल ईवेंट जारी किए जाने के बारे में बताने के लिए असंभव है (बिना किसी काम के)।

    आप कोशिश कर सकते हैं (जैसा कि अन्य लोगों ने उल्लेख किया है) मूसहेल घटनाओं को पकड़ने के लिए, संभवतः स्क्रॉल (तीर, अंतरिक्ष इत्यादि) को ट्रिगर कर सकते हैं, जो किसी भी कुंजी पर कीडाउन घटना को पकड़ने की कोशिश कर रहे हैं, यह जांचते हुए कि कौन सा तत्व वर्तमान में केंद्रित है, क्योंकि आप उदाहरण के लिए कर सकते हैं इनपुट फ़ील्ड में टाइप करते समय तीर कुंजियों का उपयोग करके स्क्रॉल नहीं करें। सामान्य रूप से जटिल और गन्दा स्क्रिप्ट होगी।

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

    +0

    धन्यवाद डब्ल्यूटीके। थोड़ी देर के लिए यह सबसे अच्छा जवाब था, लेकिन दुर्भाग्यवश आपके लिए श्रीचिफ़ ने कुछ जवाब उदाहरणों के साथ आपके उत्तर पर विस्तार किया, इसलिए मैंने उन्हें बक्षीस दिया। अगर मैं इसे विभाजित कर सकता तो मैं होता! – mrtsherman

    +2

    यह ठीक है। यह बक्षीस के बारे में नहीं बल्कि ज्ञान फैलाने और प्राप्त करने के बारे में है :) – WTK

    1

    आप तैयार होने पर स्क्रॉल स्थिति देख सकते हैं। जब आप स्क्रॉल ईवेंट पर आग लगते हैं तो यह सुनिश्चित करने के लिए जांचें कि पेज लोड होने पर स्क्रॉल स्थिति अलग है। पृष्ठ स्क्रॉल होने के बाद अंत में संग्रहीत मूल्य को साफ़ करना सुनिश्चित करें।

    $(function() { 
        var loadScrollTop = ($(document).scrollTop() > 0 ? $(document).scrollTop() : null); 
        $(document).scroll(function (e) { 
         if ($(document).scrollTop() !== loadScrollTop) { 
          // scroll code here! 
         } 
         loadScrollTop = null; 
        }); 
    }); 
    
    +0

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

    0

    यह बहुत उपयोगी पाया गया। यहां इतने इच्छुक लोगों के लिए एक कॉफ़ीस्क्रिप्ट संस्करण है।

    $ -> 
        S.userScroll = false 
    
        # reset flag on back/forward 
        if $.history? 
        $.history.init (hash) -> 
         S.userScroll = false 
    
        mouseEvent = (e)-> 
        S.userScroll = true 
    
        $(document).keydown (e) -> 
        importantKey = (e.which == 33 or  # page up 
         e.which == 34 or # page dn 
         e.which == 32 or # spacebar 
         e.which == 38 or # up 
         e.which == 40 or # down 
         (e.ctrlKey and e.which == 36) or # ctrl + home 
         (e.ctrlKey and e.which == 35) # ctrl + end 
        ) 
        if importantKey 
         S.userScroll = true; 
    
        # Detect user scroll through mouse 
        # Mozilla/Webkit 
        if window.addEventListener 
         document.addEventListener('DOMMouseScroll', mouseEvent, false); 
    
        # for IE/OPERA etc 
        document.onmousewheel = mouseEvent; 
    
    2

    हां, यह 100% संभव है। मैं वर्तमान में इस एप्लिकेशन का उपयोग कर रहा हूं जहां आईई एक आवश्यकता नहीं है - क्लाइंट केवल सामना कर रहा है। जब मेरा बैकबोन ऐप एक एनीमेशन शुरू करता है जहां स्क्रॉल बदल जाता है - स्क्रॉल होता है लेकिन इन ईवेंट कैप्चर को ट्रिगर नहीं करता है। यह एफएफ, सफारी & क्रोम नवीनतम में परीक्षण किया जाता है।

    $('html, body').bind('scroll mousedown wheel DOMMouseScroll mousewheel keyup', function(evt) { 
        // detect only user initiated, not by an .animate though 
        if (evt.type === 'DOMMouseScroll' || evt.type === 'keyup' || evt.type === 'mousewheel') { 
        // up 
        if (evt.originalEvent.detail < 0 || (evt.originalEvent.wheelDelta && evt.originalEvent.wheelDelta > 0)) { 
        // down. 
        } else if (evt.originalEvent.detail > 0 || (evt.originalEvent.wheelDelta && evt.originalEvent.wheelDelta < 0)) { 
        } 
    } 
    }); 
    
    +0

    सुझाव के लिए धन्यवाद। हालांकि, यह एक द्विआधारी समाधान है - जावास्क्रिप्ट आरंभ स्क्रॉल बनाम गैर-जेएस स्क्रॉल का पता लगाता है। मुझे वास्तव में एक टर्नरी समाधान की आवश्यकता है। (जावास्क्रिप्ट, उपयोगकर्ता, ब्राउज़र)। – mrtsherman

    0

    यदि आप एक बेहतर उत्तर की तुलना में JQuery का उपयोग कर रहे हैं, जाहिर है - मैं बस इसे अपने आप से बाहर कर रहा हूं।

    देखें: Detect jquery event trigger by user or call by code

    +0

    सुझाव के लिए धन्यवाद। हालांकि, यह एक द्विआधारी समाधान है - जावास्क्रिप्ट आरंभ स्क्रॉल बनाम गैर-जेएस स्क्रॉल का पता लगाता है। मुझे वास्तव में एक टर्नरी समाधान की आवश्यकता है। (जावास्क्रिप्ट, उपयोगकर्ता, ब्राउज़र)। Sidenote, jQuery आपके propsed समाधान के लिए एक आवश्यकता नहीं है। – mrtsherman

    0

    करने के बारे में:

    विशेष रूप से, जब वापस बटन का उपयोग कर एक ब्राउज़र अंतिम ज्ञात स्क्रॉल स्थिति के लिए कूद कर सकते हैं।

    पृष्ठ को प्रस्तुत करने के बाद बहुत जल्द आग लगती है। आप केवल स्क्रॉल इवेंट को 1 सेकंड या उससे भी कम समय में सूचीबद्ध करने में देरी कर सकते हैं।

    +0

    यह एक मजबूत समाधान नहीं होगा। कूदने का समय पृष्ठ लोड समय पर निर्भर है। ब्राउज़र पूरी तरह से लोड होने तक कूदने में देरी करता है। यह पेज तत्वों को रोकता है जो दृश्यमान स्क्रॉलिंग से पेज ऊंचाई (छवियों की तरह) को लोड और बदलते हैं। – mrtsherman

    0

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

    उदाहरण के लिए, कोड इस तरह का काम करेगा:

    // Element that needs to be scrolled 
    var myElement = document.getElementById('my-container'); 
    
    // Flag to tell if the change was programmatic or by the user 
    var ignoreNextScrollEvent = false; 
    
    function setScrollTop(scrollTop) { 
        ignoreNextScrollEvent = true; 
        myElement.scrollTop = scrollTop 
    } 
    
    myElement.addEventListener('scroll', function() { 
        if (ignoreNextScrollEvent) { 
         // Ignore this event because it was done programmatically 
         ignoreNextScrollEvent = false; 
         return; 
        } 
    
        // Process user-initiated event here 
    }); 
    

    फिर जब आप setScrollTop() फोन, स्क्रॉल घटना, ध्यान नहीं दिया जाएगा, जबकि अगर माउस, कीबोर्ड या किसी अन्य तरीके से, के साथ उपयोगकर्ता स्क्रॉल घटना संसाधित की जाएगी।

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