2012-12-20 12 views
13

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

तो हमारे पास एक पृष्ठ है जिसमें पहले से ही jQuery (1.4) है, और सबकुछ ठीक काम करता है, सिवाय इसके कि उपयोगकर्ता और मेरा कोड दोनों तत्वों पर "क्लिक" ईवेंट सुन रहे हैं, और उनके पहले कुछ चल रहे हैं, इसलिए कुछ वे घटनाएं जो झूठी वापसी करती हैं, jQuery प्रचार को रोकता है और मेरी घटना कभी भी ट्रिगर नहीं होती है। मुझे पहले जाने के लिए मेरी घटना की ज़रूरत है। उपयोगकर्ता अभी भी काम करने के लिए मेरी ऑनक्लिक कार्यक्षमता की अपेक्षा कर रहा है।

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

मुझे पता है कि, ब्राउज़र के आधार पर, वे addEventListener/removeEventListener या attachEvent/detachEvent का उपयोग कर रहे हैं। अगर केवल मुझे पहले से जोड़े गए ईवेंट की एक सूची मिल सकती है, तो मैं उन्हें जिस क्रम में चाहता था उसे पुनर्जीवित कर सकता था, लेकिन मुझे यह नहीं पता कि कैसे। क्रोम निरीक्षण के माध्यम से डोम के माध्यम से देखकर मुझे कहीं भी बाध्य नहीं देखा जाता है (वस्तु पर नहीं, खिड़की या दस्तावेज पर नहीं)।

मुझे बस इतना ही पता लगाने की कोशिश कर रहा है कि jQuery कहां से सुनता है। अपने स्वयं के कार्यक्रमों के क्रम को नियंत्रित करने में सक्षम होने के लिए, jQuery को कंबल से कहीं और सुनना चाहिए और फिर अपने कार्यों को सही तरीके से बंद करना चाहिए? अगर मैं यह पता लगा सकता हूं कि यह कहां किया गया है, तो मुझे यह सुनिश्चित करने में कुछ अंतर्दृष्टि मिल सकती है कि मेरी घटना हमेशा पहले होती है। या शायद कुछ जावास्क्रिप्ट एपीआई है जो मैं Google पर नहीं ढूंढ पा रहा हूं।

कोई सुझाव? फिर अपने घटना बाध्य करने के लिए

$.fn.bindFirst = function(name, fn) { 
    var elem, handlers, i, _len; 
    this.bind(name, fn); 
    for (i = 0, _len = this.length; i < _len; i++) { 
    elem = this[i]; 
    handlers = jQuery._data(elem).events[name.split('.')[0]]; 
    handlers.unshift(handlers.pop()); 
    } 
}; 

,:

$(".foo").bindFirst("click", function() { /* Your handler */ }); 

आसान peasy

+1

नहीं, डीओएम से 'addEventListener' द्वारा आयोजित घटनाओं को प्राप्त करना संभव नहीं है। आपके पास एकमात्र संदर्भ है जो jQuery की 'डेटा' ऑब्जेक्ट है। – Bergi

+0

बीटीडब्ल्यू, "जादू" होता है [यहां] (https://github.com/jquery/jquery/blob/master/src/event.js#L93) – Bergi

+1

उपयोगकर्ता ईवेंट प्रचार क्यों रोक रहे हैं? –

उत्तर

2

जैसा कि बर्गी और क्रिस हेल्ड ने टिप्पणियों में कहा था, यह पता चला है कि डीओएम से मौजूदा घटनाओं को पाने का कोई तरीका नहीं है, और घटनाओं को "पहले" सम्मिलित करने का कोई तरीका नहीं है। उन्हें डिजाइन द्वारा डाले गए क्रम में निकाल दिया गया है, और डिजाइन द्वारा छुपाया गया है। जैसा कि कुछ पोस्टर्स का उल्लेख है कि आपके पास jQuery के उसी उदाहरण के माध्यम से जोड़े गए लोगों तक पहुंच है जिसे आप jQuery के डेटा के माध्यम से उपयोग कर रहे हैं, लेकिन यह है।

+2

गलत। 'var oldclickevent = element.onclick; element.onclick = function() {doThisfFirst(); oldclickevent();} ' – nothingisnecessary

+0

fiddle: https://jsfiddle.net/uxdhzfz1/ ... और मिश्रण में jQuery जोड़ने के लिए, क्रिस हेल्ड के जवाब के साथ वृद्धि .. – nothingisnecessary

+0

मैंने इसे इस धागे में एक और टिप्पणी में शामिल किया, लेकिन मुझे लगता है कि मैं इसे प्रश्न में ले जाऊंगा: जबकि मैं यह भी मानता हूं कि मैं इन कार्यों के डिफ़ॉल्ट कार्यान्वयन को ओवरराइड नहीं करना चाहता हूं, यह अभी भी ' टी ने मूल समस्या हल नहीं की है। अगर मैं addEventListener नामक अन्य लोगों के सामने दौड़ने के लिए पर्याप्त जल्दी दौड़ सकता था, तो मैं सही रूप से एडवेन्ट लिस्टनर कहलाता था और बाद में श्रोताओं के सामने था जो डिफ़ॉल्ट कार्यान्वयन को ओवरराइड करने के बजाय जोड़े गए थे। – Scott

15

हम सिर्फ एक छोटे से jQuery विस्तार है कि घटना श्रृंखला के सिर पर घटनाओं सम्मिलित करता जोड़कर इस हल!

+1

एक उपयोगी फ़ंक्शन के दौरान, मुझे लगता है कि केवल मेरी घटना को उन घटनाओं की शुरुआत में डालेंगे जो jQuery के मेरे संस्करण (1.8) का उपयोग करके कतारबद्ध थे, लेकिन पृष्ठ में कहीं और जोड़े गए ईवेंट मेरे jQuery के माध्यम से नहीं थे, फिर भी प्राथमिकता ले सकते थे। – Scott

+2

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

+0

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

0

बस ऐसा कहा जाता है, मुझे लगता है कि यदि आप इन कार्यों के मूल कार्यान्वयन को ओवरराइड करते हैं तो यह संभव हो सकता है। यह बीएडी अभ्यास है - मूल कार्यान्वयन को बदलने के लिए लाइब्रेरी विकसित करते समय बहुत बुरा अभ्यास, क्योंकि यह आसानी से अन्य पुस्तकालयों के साथ संघर्ष कर सकता है।

हालांकि, संपूर्णता के लिए, यहाँ एक संभावना (पूरी तरह से अपरीक्षित, सामान्य अवधारणा सिर्फ प्रदर्शन) है:

// override createElement() 
var temp = document.createElement; 
document.createElement = function() { 
    // create element 
    var el = document.createElement.original.apply(document, arguments); 

    // override addEventListener() 
    el.addEventListenerOriginal = el.addEventListener; 
    el._my_stored_events = []; 

    // add custom functions 
    el.addEventListener = addEventListenerCustom; 
    el.addEventListenerFirst = addEventListenerFirst; 
    // ... 
}; 
document.createElement.original = temp; 

// define main event listeners 
function myMainEventListeners(type) { 
    if (myMainEventListeners.all[type] === undefined) { 
     myMainEventListeners.all[type] = function() { 
      for (var i = 0; i < this._my_stored_events.length; i++) { 
       var event = this._my_stored_events[i]; 
       if (event.type == type) { 
        event.listener.apply(this, arguments); 
       } 
      } 
     } 
    } 
    return myMainEventListeners.all[type]; 
} 
myMainEventListeners.all = {}; 

// define functions to mess with the event list 
function addEventListenerCustom(type, listener, useCapture, wantsUntrusted) { 
    // register handler in personal storage list 
    this._my_stored_events.push({ 
     'type' : type, 
     'listener' : listener 
    }); 

    // register custom event handler 
    if (this.type === undefined) { 
     this.type = myMainEventListeners(type); 
    } 
} 

function addEventListenerFirst(type, listener) { 
    // register handler in personal storage list 
    this._my_stored_events.push({ 
     'type' : type, 
     'listener' : listener 
    }); 

    // register custom event handler 
    if (this.type === undefined) { 
     this.type = myMainEventListeners(type); 
    } 
} 

// ... 

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

+1

जबकि मैं यह भी मानता हूं कि मैं इन कार्यों के डिफ़ॉल्ट कार्यान्वयन को ओवरराइड नहीं करना चाहता, फिर भी यह मूल समस्या का हल नहीं होता। अगर मैं addEventListener नामक अन्य लोगों के सामने दौड़ने के लिए पर्याप्त जल्दी दौड़ सकता था, तो मैं बाद में एडवेन्ट लिस्टनर कह सकता था और श्रोताओं के सामने जो बाद में जोड़ा गया था। – Scott

+0

लॉल, बहुत अच्छा बिंदु :- डी – opensourcejunkie

1

मुझे एक विपरीत स्थिति का सामना करना पड़ता है जहां मुझे एक पुस्तकालय शामिल करने के लिए कहा गया था, जो हमारी वेबसाइट पर event.stopImmediatePropagation() तत्व का उपयोग करता है। तो मेरे कुछ कार्यक्रम हैंडलर छोड़ दिए गए हैं। यहाँ मैं क्या कर (के रूप में दिए here) है:

<span onclick="yourEventHandler(event)">Button</span> 

चेतावनी: इस नहीं घटनाओं बाध्य करने के लिए सिफारिश की तरह, अन्य डेवलपर्स इस के लिए आप की हत्या हो सकती है।

+1

'event.stopImmediatePropagation()' मेरे लिए काम किया – webmaster