This is not the way you are supposed to go about using events. An
event fires, any attached handlers will be executed because the event
fired, they do not need to know of any other handlers or their
actions, because they were attached to this specific event.

You should attach the handlers as if they are being executed at the
exact moment when the event fires, at the exact same time, not as a
stack depending on order. The way you're doing it now can lead you
into several hard-to-debug problems, where one handler is attached
earlier (and therefore comes first in the stack) due to a race
condition or lazy loading.

Imo, if you really need to fire a stack of functions which you may
cancel along the way, implement it as a stack, though if the
functionality of your Fiddle is actually what you need I'm sure
there's a better way.

In any case, to show an example, a simple way would be:
```
element.addEvent('click', function(event){
    var stack = this.retrieve('clickStack', []);
    for (var i = 0, l = stack.length; i < l; ++i){
        if (stack[i].call(this, event) === false) break;
    }
});
element.retrieve('clickStack', []).push(fn);
```
(like: http://jsfiddle.net/9upWw/7/ )


A more generic example would be something like (excuse the function name):
```
Element.implement('addEventStack', function(type, fn){
    var stack = this.retrieve(type + 'Stack');
    if (!stack){
        stack = [];
        this.store(type + 'Stack', stack);
        this.addEvent('click', function(event){
            var stack = this.retrieve(type + 'Stack');
            for (var i = 0, l = stack.length; i < l; ++i){
                stack[i].call(this, event);
                if (event.stoppedImmediatePropagation) break;
            }
        });
    }
    stack.push(fn);
});
DOMEvent.implement('stopImmediatePropagation', function(){
    this.stoppedImmediatePropagation = true;
});
```
(like: http://jsfiddle.net/9upWw/8/ )

Reply via email to