Thursday, October 13, 2005

JavaScript: Making sure the right object gets the onclick

Having just discovered how to do something I couldn't work out before, I thought I'd share it, in case other people are as dumb as I am.

In brief:
I worked out how to use a closure as an onclick handler.

Less briefly:
My problem was that onclick events are not called from any particular object scope. So if i had a javascript object like this:


..you can't use your object's handleClick function like you want to. Eg if you did this:



..you are expecting that clicking button1 will give you an alert saying "Jeremy", but you actually get an error saying that "this" is not defined. That's because when the handleClick function is called by the button being clicked, it's not being called as part of an object, it's just being called as a normal function.

A week or two ago I solved this problem the wrong way, by making a global list of all myObjects created, and writing a single click handler. The list allocated ids to objects, and the "super" click handler trawled up the DOM tree looking for an id it issued, found that object, and called it's click handler.

That worked but it just seemed wrong; I knew I was supposed to use a closure for this, but I couldn't work out how. Then I discovered this:


This is a function that returns a function. The anonymous function that is returned by getClickHandler has a lexically-scoped reference to it's owner object. Now you can say:


..and when button1 or button2 get clicked on, the right thing happens. Shiny! I've rewritten my TiddlyWiki games to provide themselves with a unique id using a static class variable, and this trick closure to handle the onclick stuff, and it's chopped a fair few lines of code from the plugins.

So anyway, this is probably old news to some, but hopefully I've saved some time for someone else out there.

Comments: Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?