Duplicated event object arguments when using Prototype’s bindAsEventListener
Thursday, October 26th, 2006David Flanagan has discovered that an event object is passed to event handlers set with the Microsoft proprietary attachEvent() method. Although this object is not the same as window.event, but it still has the same properties.
At the beginning of this month, I realized this too, when I worked with Prototype’s bindAsEventListener.
I was writing a function (called doClick) in an easy ajaxed faq - if you click on the question, you can see the answer - which I bound with the bindAsEventListener to the onclick event.
doClick: function(event, id) {
var id = id || this.getId(Event.element(event).href);
doAjax("faq", "get_answer", id, this.update.bind(this));
}
a.observe("click", this.doClick.bindAsEventListener(this));
At the same time I tried to use this function when the DOM has been loaded, because I wanted the given question to load automaticallay, if the hash of the URL contains one of the identifier of the answer (eg. /faq#123). To put it an other way: I wanted doClick not to run only if there is a real click, but also when I want it to run. Something like this:
if (location.hash) {
this.doClick({}, this.getId(location.hash));
}
Since rc1 version of Prototype, the bindAsEventListener accepts additional parameters.
Function.prototype.bindAsEventListener = function(object) {
var __method = this, args = $A(arguments), object = args.shift();
return function(event) {
return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
}
}
I didn’t use this feature here, so I supposed when the doClick is triggered by an event it will get only one parameter - the event object of course - as usual.
But when executing the first test, I realized that there were two parameters, namely the event object once again!
I dug into Prototype and I saw that this is not accidentally, the parameters of the closure are appended to the parameter list. At the end of the expression, the concat($A(arguments)) contains the event object once again. I don’t know why it is there, but I suspect this isn’t meant to be there. Prove me wrong. :)
And according David’s post referred to above, this made obvious to me that IE passes the event object - I didn’t analyse if this is equal to window.event - to the attached function, because the doClick function received two parameters in IE too not just in Firefox which cannot be occur if only window.event exists.
A private sidenote, but at the same time an interesting issue: It is strange to see that members of the scene bump into these questions nearly at the same time. I was looking into this same issue at the beginning of the month, but I simply could not find any details. I thought I was to blame, and I did not want to get into an embarrassing situation by drawing attention to something that I should now. But since this was not the first time that I had realized something in time, but did not care to post about it, I decided to to share these even if I make a mistake. A hundred mistake means a hundred tries. But at least I try! :)