Ken Snyder wrote:
> Along with all this Event handling discussion, I'd like to throw in my 
> ideas for a rewrite of Event.observe et al before I test and submit as a 
> patch.  My proposed changes allow the traditional Event.stopObserving() 
> and simplify some of the current messaging ideas.  Please provide feedback.
>   
Colin, thanks for pointing out that my observer array will slow things 
down in many cases. I really like your implementation, especially the 
way you keep a different EventCache object.  One thing I wonder, though, 
if like you said your function returns an index--an array index could be 
problematic, but why not use an object as a cache?  Consider the draft 
below.

--Ken

Object.extend(Event, {
  //...
  // the cache of observers
  observers: {},
  // the current position in our cache
  cacheIdx: 0,
  // added return of cacheIdx to allow Event.stopObserving(idx)
  observe: function( element, event, observer, useCapture ) {
    element = $(element);
    useCapture = useCapture || false;
    element[this._addFnName](this._eventName(event), observer, useCapture);
    this.cacheIdx++;
    this.observers[this.cacheIdx] = [element, event, observer, useCapture];
    return cacheIdx;
  },
  stopObserving: function( element, event, observer, useCapture ) {
    if( typeof arguments[0]=='number' ) {
      this._cancel(arguments[0]);
    } else {
      element = $(element);
      useCapture = useCapture || false;
      element[this._removeFnName](this._eventName(event), observer, 
useCapture);
      //
      // The current implementation seems not to clear the cache like this
      //
      for( idx in this.observers ) {
        if( this.observers[idx][0]==element &&
          this.observers[idx][1]==event &&
          this.observers[idx][2]==observer &&
          this.observers[idx][3]==useCapture) {
          delete this.observers[idx];
          break;
        }
      }
      //
      //
      //
    }
  },
  unloadCache: function() {
    for( idx in this.observers ) {
      this._cancel(idx);
    }
  },
  //
  // New methods
  //
  // function that actually detaches the event and clears from cache
  _cancel: function(idx) {
    var handle = this.observers[idx];
    try {
      handle.element[this._removeFnName](this._eventName(handle.event), 
handle.observer, handle.useCapture);
      delete this.observers[idx];
    } catch(e) {}
  },  
  // New method: cancel all the observers associated with a particular 
element for a particular event
  stopObservingElementEvent: function( element, event ) {
    element = $(element);
    for( idx in this.observers ) {
      if( this.observers[idx][0]==element && this.observers[idx][1]==event )
        this._cancel[idx];
    }    
  },
  // New method: cancel all the observers associated with a particular 
element
  stopObservingElement: function( element ) {
    element = $(element);
    for( idx in this.observers ) {
      if( this.observers[idx][0]==element )
        this._cancel[idx];
    }
  }
};
// cross-browser function and event naming
if( window.addEventListener ) {
  Event._addFnName = 'addEventListener';
  Event._removeFnName = 'removeEventListener';
  if( navigator.appVersion.match(/Konqueror|Safari|KHTML/) )
    Event._eventName = function(name) { return name=='keypress' ? 
'keydown' : name; };
  } else {
    Event._eventName = function(name) { return name; };
  }
} else if( window.attachEvent ) {
  Event._addFnName = 'attachEvent';
  Event._removeFnName = 'detachEvent';  
  Event._eventName = function(name) { return 'on'+name; };
  // garbage collect for IE
  window.attachEvent('onunload', Event.unloadCache);
}


Using an indexed object as a cache even opens up the possibility of 
using my original API suggestion:
...
  observe: function( element, event, observer, useCapture ) {
    element = $(element);
    useCapture = useCapture || false;
    element[this._addFnName](this._eventName(event), observer, useCapture);
    this.cacheIdx++;
    this.observers[this.cacheIdx] = [element, event, observer, useCapture];
    return { cancel: function() { Event._cancel(cacheIdx); } };
  }
...
  stopObserving: function( element, event, observer, useCapture ) {
    if( typeof arguments[0]=='object' && arguments[0].cancel ) {
     arguments[0].cancel();
    } else {
  ...

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to