2012-03-14 3 views
17

इस साइट पर अब सबसे लोगों तक शायद पता है कि कर रहे हैं:क्यों जावास्क्रिप्ट घटना प्रतिनिधिमंडल चरम पर नहीं लेते?

$("#someTable TD.foo").click(function(){ 
    $(e.target).doSomething(); 
}); 

जा रहा है प्रदर्शन करने के लिए ज्यादा बदतर:

$("#someTable").click(function(){ 
    if (!$(e.target).is("TD.foo")) return; 
    $(e.target).doSomething(); 
}); 

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

किसी भी तरह, मैंने इस सिद्धांत को एक सहकर्मी को समझाया, और उनकी प्रतिक्रिया "अच्छी तरह से, साइट-व्यापी घटकों (उदाहरण के लिए एक तिथि लेने वाला इनपुट) क्यों रुकती है? क्यों न केवल प्रत्येक प्रकार के लिए एक हैंडलर बांधें शरीर के लिए घटक का? " मेरे पास कोई अच्छा जवाब नहीं था।

स्पष्ट रूप से प्रतिनिधिमंडल रणनीति का उपयोग करना मतलब है कि आप घटनाओं को कैसे अवरुद्ध करते हैं, इसलिए यह एक नकारात्मक है। साथ ही, आप hypothetically एक पृष्ठ हो सकता है जहां आपके पास "TD.foo" है जो पर कोई ईवेंट संलग्न नहीं होना चाहिए। लेकिन, यदि आप समझते हैं और ईवेंट बुलबुले परिवर्तन के आसपास काम करने के इच्छुक हैं, और यदि आप "टीडी पर .foo डालते हैं, तो यह नीति को लागू करता है, यह हमेशा ईवेंट को हुक अप करने जा रहा है", इनमें से कोई भी ऐसा नहीं लगता है बड़ी बात।

मुझे लगता है कि मुझे कुछ याद आना चाहिए, इसलिए मेरा सवाल यह है कि: बॉडी में सभी साइट-व्यापी घटकों के लिए सभी घटनाओं को प्रस्तुत करने के लिए कोई अन्य नकारात्मक पक्ष है (जैसा कि उन्हें सीधे शामिल HTML तत्वों में बाध्य करने का विरोध किया गया है , या उन्हें एक गैर-बॉडी पैरेंट तत्व में प्रतिनिधि)?

+0

मेरा मानना ​​है कि यह प्राथमिकता का मामला है और एक मामला-दर-मामला परिदृश्य है । मेरा मतलब यह है कि आपको पहले जितना संभव हो सके पठनीय होने के लिए कोड लिखना चाहिए। इस तरह आप या कोई और बाद में कोड में आ सकता है और उसके बाद कोड का परीक्षण कर सकता है। एक बार ऐसा करने के बाद आप यह देखने के लिए जांच सकते हैं कि कोड अच्छी तरह से प्रदर्शन करता है और इसे आवश्यकतानुसार अनुकूलित करता है। आपके विशिष्ट परिदृश्य में, $ ("someTable TD.foo") उसमें वापसी के साथ परिदृश्य की तुलना में पढ़ने, प्रबंधित करने और अनुसरण करना आसान है। कोई अन्य कोड पढ़ सकता है और गलत व्याख्या कर सकता है, जिससे वे अपने परिवर्तनों के साथ गलतियों को पेश कर सकते हैं। बस मेरी राय – evasilchenko

+0

मैं पूर्ण और कुल समझौते में हूं: डेवलपर्स को ऑप्टिमाइज़ेशन के बारे में चिंता किए बिना पहले डिजाइन करना चाहिए, और केवल बाद में उपयुक्त के रूप में अनुकूलित करना चाहिए। हालांकि, यह पूरी चीज एक वास्तविक डिजाइन को अनुकूलित करने के लिए वास्तविक जीवन की आवश्यकता से बाहर आई थी (हमारे पास एक अच्छा पृष्ठ था जब तक कि हमारे ग्राहकों ने हजारों और हजारों पंक्तियों के साथ इसका उपयोग करने का फैसला नहीं किया), इसलिए हम सबसे अच्छी रणनीति के साथ आने की कोशिश कर रहे थे उस अनुकूलन को संभालने के लिए। – machineghost

+1

संभावित डुप्लिकेट [क्या सभी jquery घटनाओं को $ (दस्तावेज़) तक बाध्य होना चाहिए?] (Http://stackoverflow.com/q/12824549/1048572) – Bergi

उत्तर

20

जो आप खो रहे हैं वह प्रदर्शन के विभिन्न तत्व हैं।

क्लिक हैंडलर सेट करते समय आपका पहला उदाहरण खराब होता है, लेकिन वास्तविक ईवेंट ट्रिगर होने पर बेहतर प्रदर्शन करता है।

क्लिक हैंडलर सेट करते समय आपका दूसरा उदाहरण बेहतर प्रदर्शन करता है, लेकिन वास्तविक ईवेंट ट्रिगर होने पर काफी खराब प्रदर्शन करता है।

सभी घटनाओं के एक शीर्ष स्तर वस्तु (दस्तावेज़) पर रखा गया है, तो आप चयनकर्ताओं का एक विशाल सूची जिस क्रम हैंडलर समारोह इसके साथ चला जाता है खोजने के लिए हर घटना पर जांच करने के लिए होगा। यह बहुत ही मुद्दा यह है कि jQuery ने .live() विधि को हटा दिया क्योंकि यह दस्तावेज़ ऑब्जेक्ट पर सभी घटनाओं को देखता है और जब .live() ईवेंट हैंडलर पंजीकृत होते थे, तो प्रत्येक ईवेंट का प्रदर्शन खराब था क्योंकि इसे प्रत्येक ईवेंट की तुलना बहुत अधिक और चयनकर्ताओं की तुलना करना पड़ता था उस घटना के लिए उचित घटना हैंडलर खोजने के लिए। बड़े पैमाने पर काम के लिए, घटना को ट्रिगर करने वाली वास्तविक वस्तु के करीब घटना को बाध्य करने के लिए यह बहुत अधिक कुशल है। यदि ऑब्जेक्ट गतिशील नहीं है, तो ईवेंट को उस ऑब्जेक्ट पर बाध्य करें जो इसे ट्रिगर करेगा। जब आप पहली बार घटना को बांधते हैं, तो इससे थोड़ा अधिक सीपीयू खर्च हो सकता है, लेकिन वास्तविक घटना ट्रिगरिंग तेज होगी और स्केल होगी।

jQuery के .on() और .delegate() इसका उपयोग किया जा सकता है, लेकिन यह अनुशंसा की जाती है कि आप एक पूर्वजों की वस्तु को ढूंढें जो ट्रिगरिंग ऑब्जेक्ट के जितना संभव हो सके। यह एक शीर्ष स्तर की वस्तु पर कई गतिशील घटनाओं के निर्माण को रोकता है और ईवेंट हैंडलिंग के लिए प्रदर्शन में गिरावट को रोकता है।

अपने उदाहरण में ऊपर, यह पूरी तरह से करने के लिए उचित है:

$("#someTable").on('click', "td.foo", function(e) { 
    $(e.target).doSomething(); 
}); 

है कि आप सभी पंक्तियों के लिए एक क्लिक हैंडलर में से एक कॉम्पैक्ट प्रतिनिधित्व देना होगा और यह भी रूप में शामिल किया/हटा दिया पंक्तियों काम करने के लिए जारी रहेगा।

लेकिन, इस के रूप में ज्यादा मतलब नहीं होगा: क्योंकि इस पेज में अन्य सभी शीर्ष स्तर की घटनाओं के साथ में टेबल घटनाओं मिश्रण किया जाएगा जब ऐसा करने के लिए कोई वास्तविक जरूरत नहीं है

$(document).on('click', "#someTable td.foo", function(e) { 
    $(e.target).doSomething(); 
}); 

। आप घटनाओं को संभालने के किसी भी लाभ के बिना केवल ईवेंट हैंडलिंग में प्रदर्शन समस्याओं के लिए पूछ रहे हैं।

तो, मुझे लगता है कि आपके प्रश्न का संक्षिप्त उत्तर यह है कि सभी घटनाओं को एक शीर्ष स्तर की जगह पर संभालने के लिए प्रदर्शन के मुद्दों की ओर जाता है जब ईवेंट ट्रिगर होता है क्योंकि कोड को हल करना होता है कि कौन से हैंडलर को ईवेंट प्राप्त करना चाहिए एक ही स्थान पर कई घटनाओं को संभाला जा रहा है। जेनरेटिंग ऑब्जेक्ट के करीब घटनाओं को संभालने के रूप में व्यावहारिक रूप से घटना को अधिक कुशलता से संभालने में मदद मिलती है।

+1

उस विस्तृत स्पष्टीकरण के लिए धन्यवाद। इस मामले में हम (हज़ारों टीडी के साथ एक टेबल) देख रहे थे, इवेंट हुकअप प्रदर्शन बाधा था, लेकिन आपकी व्याख्या ने मुझे यह समझने में मदद की कि हमारी साइट पर कई अन्य प्रासंगिक मामलों में इवेंट रिज़ॉल्यूशन प्रदर्शन घटना से अधिक मायने रखता है हुकअप प्रदर्शन (और दस्तावेज के लिए बहुत अधिक बाध्यकारी उस संकल्प प्रदर्शन पर नकारात्मक प्रभाव डालता है)। तो ... हम अब वैश्विक स्तर पर बाध्यकारी नहीं होंगे :-) – machineghost

3

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

व्यक्तिगत रूप से, मुझे लगता है कि थोड़ा प्रतिनिधिमंडल अच्छा है, लेकिन इसमें से अधिकतर इसे हल करने से अधिक समस्याएं उत्पन्न कर देगा।

3
  • यदि आप कोई नोड हटाते हैं, तो संबंधित श्रोताओं को स्वचालित रूप से हटाया नहीं जाता है।
  • कुछ घटनाओं बस नहीं बुलबुला
  • विभिन्न पुस्तकालयों घटना प्रसार को रोकने के प्रणाली बाधित कर सकते हैं करते हैं (लगता है कि आप का उल्लेख किया है कि एक)