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
-~----------~----~----~----~------~----~------~--~---

Reply via email to