2012-02-19 17 views
5

को सुनना मेरे पास कई बच्चों के साथ एक स्क्रॉल करने योग्य तत्व है और संबंधित विकल्पों के साथ एक चयन टैग है।जेएस .scroll() कुशलतापूर्वक

मैं तत्वों .scrollTop()

यह कुशलतापूर्वक कैसे करना है के आधार पर की चुनिंदा मान बदलने के लिए करना चाहते हैं? मैंने एक सरणी में बच्चों के .offset().top को स्टोर करने और इसके माध्यम से लूपिंग के बारे में सोचा। हालांकि, ब्राउज़र इसे संभाल नहीं करता है। मैं .setTimeout() ध्वज बनाने का प्रयास कर सकता हूं, लेकिन यह साफ नहीं लगता है।

r = $('ul') 
    offsets = [] 
    r.find('li').each((index) -> 
     offsets[index] = $(this).offset().top 
    ) 
    r.bind('scroll', -> 
     // while loop checking .scrollTop() > offsets[n] is slow 
     // maybe spams to many .scroll events? 
    ) 

उत्तर

9

कैसे @osoner ने कहा कि स्क्रॉल में सभी गणना करने के बजाय भी हैंडलर, आप एक अंतराल (उदाहरण के लिए, 'fooscroll') के बाद हैंडलर में एक और घटना को आग लगाना, और फिर आपके बच्चे के सभी तत्व सदस्यता लेते हैं घटना, और सेट की गई स्थितियों के आधार पर खुद को अपडेट करें।

var scrollTimer; 
$(window).on('scroll', function(e) { 
    if (scrollTimer) { clearTimeout(scrollTimer); } 
    scrollTimer = setTimeout(function() { 
     $(window).trigger('fooscroll'); 
    }, 200); 
}); 

$('li').on('fooscroll', function() { 
    // Check scrollTop or whatever... 
}); 
+0

मुझे यह बेहतर पसंद है (नफरत 'सेट इंटरवल')। धन्यवाद! – mreq

+0

क्या मैं इसे सही देख रहा हूं कि यदि उपयोगकर्ता 200ms के लिए स्क्रॉलिंग रोकता है तो ईवेंट "fooscroll" केवल निकाल दिया जाता है? – Simon

+0

@ सिमॉन: हाँ, आप सही हैं। स्पष्टीकरण के लिए, नहीं, यह स्क्रॉलिंग को 'थ्रॉटल' नहीं करता है। यदि आप केवल एक बार स्क्रॉल करने के बाद प्रत्येक 200ms स्क्रॉल करना चाहते हैं, तो आपको इसे अलग-अलग करना होगा। – hayavuk

6

आपको this suggestion from John Resig पढ़ना चाहिए। मूल रूप से जब भी उपयोगकर्ता स्क्रॉल करता है और उस अंतराल फ़ंक्शन के साथ इच्छित कार्रवाई करता है जो इस ध्वज को जांचता है।

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