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.
Consider this API:
var myHandle = Event.observe(myElement, 'click', myFunction);
myHandle.stopObserving();
// with support for the traditional Event.stopObserving()
Event.stopObserving(myElement, 'click', myFunction);
Draft suggestion below. One thing I'm also considering is making the
handle's stopObserving function remove its own entry from the
Event.observers array, but that isn't technically necessary.
--Ken Snyder
Object.extend(Event, {
//...
// the cache of observers
observers: [],
//
// replacements for observe, stopObserving, unloadCache with
enhanced functionality
//
observe: function( element, event, observer, useCapture ) {
element = $(element);
useCapture = useCapture || false;
element[Event._addFnName](Event._eventName(event), observer,
useCapture);
var handle = {
event: event,
observer: observer,
useCapture: useCapture,
stopObserving = function() {
try {
element[Event._removeFnName](Event._eventName(event), observer,
useCapture); } catch(e) {}
}
}
Event.observers.push(handle);
return handle;
},
stopObserving: function( element, event, observer, useCapture ) {
element = $(element);
useCapture = useCapture || false;
Event._stopObservations(function(handle) {
return handle.element==element handle.event==event
handle.observer==observer handle.useCapture==useCapture;
});
},
unloadCache: function() {
Event.observers.invoke('stopObserving');
Event.observers = null;
},
//
// New methods
//
// New method: cancel all the observers associated with a particular
element for a particular event
stopObservingElementEvent: function( element, event ) {
element = $(element);
Event._stopObservations(function(handle) {
return handle.element==element handle.event==event;
});
},
// New method: cancel all the observers associated with a particular
element
stopObservingElement: function( element ) {
element = $(element);
Event._stopObservations(function(handle) {
return handle.element==element;
});
},
// internal function to cancel one or more observers
_stopObservations: function(partitioner) {
var handles = Event.observers.partition(partitioner);
if( handles[0].length ) {
handles.invoke('stopObserving');
Event.observers = handles[1];
}
}
};
// pre-define 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.addEventListener('onunload', Event.unloadCache);
}
Improvements:
- Browser capability is detected only once
- Has a simpler API
- Gives a simple way to cancel all observers for a particular element or
element-event combination
- It is simple to cache all observers associated with a particular
widget and stop all with widgetHandles.invoke('stopObserving');
- It is easily extendable (i.e. new methods such as
Event.isObservedElement() and Event.isObservedElementEvent())
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---