2015-11-27 5 views
14

1.7.3 अद्यतन के बाद प्रोटोटाइप इवेंट रजिस्ट्री के साथ कोई समस्या प्रतीत होती है, मैं क्लिक ईवेंट पर पहुंचने के लिए तत्व भंडारण पर prototype_event_registry का उपयोग कर रहा था ताकि मैं उन्हें फिर से चला सकूं।प्रोटोटाइपजेएस इवेंट रजिस्ट्री मुद्दे

ऐसा इसलिए है कि मैं घटनाओं को रोक सकता हूं और वैकल्पिक रूप से कॉलबैक के आधार पर उन्हें फिर से शुरू कर सकता हूं, सब कुछ ठीक काम कर रहा था, लेकिन 1.7.0 और 1.7.3 के लिए अंतर को देखने के बाद इसे हटाया जा रहा है?

मुझे पता है कि यह आंतरिक था और शायद मुझे इसे पहले स्थान पर उपयोग नहीं करना चाहिए था। वैसे भी, मेरे प्रश्न के नीचे:

मैंने 1.7.3 के साथ काम करने के लिए अपना कोड अपडेट किया है लेकिन यह मेरे लिए बेहद हैकी है, क्या ऐसा करने का एक बेहतर तरीका है?

/** 
* creates a toggling handler for click events taking previous click events into account. 
* 
* w.r.t stopping of a click event, handles cases where the button is a submit or a normal button. 
* in the case of a submit, calling <tt>Event.stop()</tt> should be sufficient as there are no other listeners on the button. 
* however, if a normal button has a handler that calls <tt>save()</tt>, and another handler using client code and calling stop, 
* it will not affect stopping of the event, since <tt>Event.stop</tt> only stops propagation, not other handlers! 
* 
* note that this function will always execute the specified handler before any other defined events. 
* 
* @param {Element} element the element to use for this click event 
* @param {Function} handler the handler to use for this stopping click event, if this handler returns true, 
* all other actions for the click event will be prevented 
* @returns {Element} the element that was supplied as argument 
*/ 
function stoppingClickEvent(element, handler) { 
    if (!element) throw 'cannot use method, if element is undefined'; 

    // assign default handler if none was supplied 
    handler = handler || Prototype.emptyFunction; 

    if (element.type && element.type === 'submit') { 
     element.on('click', function(submitEvent) { 
      // call the supplied handler with the current element as context and the event as argument 
      // if it returns true, we should stop the event 
      var stopEvent = handler.call(element, submitEvent); 

      if (stopEvent) { 
       // since the element's default action will be to submit a form, we prevent it 
       submitEvent.stop(); 
      } 
     }); 
    } else { 
     // prototype 1.7.3 removed support for 'prototype_event_registry', so we need to do multiple hacks here 
     // first get the window of the element so we can access the prototype 
     // event cache from the correct context (frames) 
     var elementDoc = element.ownerDocument; 
     var elementWindow = elementDoc.defaultView || elementDoc.parentWindow; 

     if (!elementWindow) { 
      throw 'cannot access the window object for element ' + element.id; 
     } 

     // we are dealing with a normal element's click event, so we don't know how many click events have been set up. 
     // capture them all so we can decide to call them or not. 
     // FIXME: need a better way of doing this 
     var registry = elementWindow['Event'].cache[element._prototypeUID || element.uniqueID] || {}, 
      events = registry['click'] || []; 

     // now that we have a copy of the events, we can stop them all and add our new handler 
     element.stopObserving('click').on('click', function(clickEvent) { 
      // call the supplied handler with the current element as context and the event as argument 
      // if it returns true, we should stop the event 
      var stopEvent = handler.call(element, clickEvent); 

      if (!stopEvent) { 
       // the event should not be stopped, run all the original click events 
       events.each(function(wrapper) { 
        wrapper.handler.call(element, clickEvent); 
       }); 
      } 
     }); 
    } 

    return element; 
} 
+1

यह घटना रजिस्ट्री 1.7.1 पुनः लिखा गया की तरह दिखता है - 'Event.cache' वस्तु के लिए सेटअप था कुछ मेमोरी लीक प्रदर्शन को बेहतर बनाने से रोकें। मुझे पूरा यकीन है कि 'तत्व। _prototypeUID' हमेशा किसी भी विस्तारित तत्व पर मौजूद होना चाहिए - लेकिन अन्यथा यह प्रति तत्व इवेंट रजिस्ट्री को संदर्भित करने का तरीका होगा। –

+0

Event.stop (e) ऐसा नहीं कर रहा है जो करना है? इसे घटना प्रसार रोकना चाहिए, है ना? –

+0

@kiran, यह प्रचार रोकता है, लेकिन बटन पर निर्दिष्ट किसी भी अतिरिक्त क्लिक हैंडलर को नहीं रोकेगा, इसलिए यह फ़ंक्शन :) – epoch

उत्तर

0

उपरोक्त कोड के साथ 3-4 महीने के लिए चलने के बाद, मैंने अंततः इसे वापस करने का फैसला किया। ऐसा लगता है कि बहुत सारे मुद्दे हैं, खासकर जब एक ही पृष्ठ पर एकाधिक फ्रेम और ईवेंट हैंडलर से निपटते हैं।

Event.cache एक विशिष्ट तत्व के लिए undefined होने वाला सबसे प्रचलित व्यक्ति है।

यह उपरोक्त गलत हैंडलिंग के कारण हो सकता है, लेकिन मुझे Event फ्रेमवर्क को किसी भी तरह गलत होने पर संदेह है, क्योंकि 1.7.0 पर वापस लौटने के बाद से मैंने जो भी मुद्दों का अनुभव किया है, पूरी तरह से ठीक करता है।

बस संदर्भ के लिए

, इस कोड को मैं अब 1.7.0 साथ उपयोग कर रहा हूँ है:

/** 
* creates a toggling handler for click events taking previous click events into account. 
* 
* w.r.t stopping of a click event, handles cases where the button is a submit or a normal button. 
* in the case of a submit, calling <tt>Event.stop()</tt> should be sufficient as there are no other listeners on the button. 
* however, if a normal button has a handler that calls <tt>save()</tt>, and another handler using client code and calling stop, 
* it will not affect stopping of the event, since <tt>Event.stop</tt> only stops propagation, not other handlers! 
* 
* note that this function will always execute the specified handler before any other defined events. 
* 
* @param {Element} element the element to use for this click event 
* @param {Function} handler the handler to use for this stopping click event, if this handler returns true, 
* all other actions for the click event will be prevented 
* @returns {Element} the element that was supplied as argument 
*/ 
function stoppingClickEvent(element, handler) { 
    if (!element) throw 'cannot use method, if element is undefined'; 

    // assign default handler if none was supplied 
    handler = handler || Prototype.emptyFunction; 

    if (element.type && element.type === 'submit') { 
     element.on('click', function(submitEvent) { 
      // call the supplied handler with the current element as context and the event as argument 
      // if it returns true, we should stop the event 
      var stopEvent = handler.call(element, submitEvent); 

      if (stopEvent) { 
       // since the element's default action will be to submit a form, we prevent it 
       submitEvent.stop(); 
      } 
     }); 
    } else { 
     // we are dealing with a normal element's click event, so we don't know how many click events have been set up. 
     // capture them all so we can decide to call them or not. 
     var registry = element.getStorage().get('prototype_event_registry') || $H(), 
      events = registry.get('click') || []; 

     // now that we have a copy of the events, we can stop them all and add our new handler 
     element.stopObserving('click').on('click', function(clickEvent) { 
      // call the supplied handler with the current element as context and the event as argument 
      // if it returns true, we should stop the event 
      var stopEvent = handler.call(element, clickEvent); 

      if (!stopEvent) { 
       // the event should not be stopped, run all the original click events 
       events.each(function(func) { 
        func.call(element, clickEvent); 
       }); 
      } 
     }); 
    } 

    return element; 
} 
संबंधित मुद्दे