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