javascriptdom-eventsyuiyui3

YUI events don't seem to work recursively


I ran across a piece of legacy YUI3 plugin code that was trying to inject itself into an event-based flow. Basically, the code would subscribe to an event X and, in the handler, do something like the following:

if (!this._hasDoneStuff) {
    doStuff();
    event.preventDefault();
    fire("theEvent", newEvent);
}

The preventDefault() call didn't seem to be working; the event continued as normal. I managed to replicate this with a small example:

        var eidCounter = 0;
        this.publish("myEvent", {
            defaultFn: function (myEvent) {
                console.log("default function hit by event " + myEvent.eid);
            },
            context: this
        });
        this.on("myEvent", function (myEvent) {
            console.log("saw & prevented " + myEvent.eid);
            myEvent.preventDefault();
            if (myEvent.eid < 3) {
                this.fire("myEvent", { eid: eidCounter++ });
            } else {
                console.log("stopped " + mikeEvent.eid);
            }
        }, this);
        this.fire("myEvent", { eid: eidCounter++ });

I would expect this to NEVER run the default function, because preventDefault() is always called. However, the actual output is:

saw & prevented 0
saw & prevented 1
saw & prevented 2
saw & prevented 3
stopped 3
default function hit by event 2
default function hit by event 1
default function hit by event 0

Thus, the preventDefault() only seems to work on the last event in the stack. This seems like a bug, but am I actually violating some part of the event API? Is there a workaround?


Solution

  • Unfortunately, YUI has always worked this way. Despite the fact that it seems odd to fire the subscribed event from the subscription, it does seem like a bug. You can file it here: https://github.com/yui/yui3/issues