PDA

View Full Version : assign event handler dynamically?


Muon
03-09-2003, 09:02 PM
I hope this isn't a stupid question...!

I have a table that I am dynamically adding some rows to on mouseOver, as a means of emulating a menu system.

Having created the new rows, it would be nice if I could then add mouseOver, mouseOut and onClick event handlers to the rows themselves.

In Flash Actionscript I could do this by using this syntax:

object.onClick = function {
statements
}

What I would like to know is if there is any equivalent means of doing this in javascript?

Cheers!

Graeme Hackston
03-09-2003, 09:45 PM
object.setAttribute('onclick',"alert(this.id)")

Graeme Hackston
03-09-2003, 09:53 PM
If you use that you'll likely run into this

myclass='blah'
if (IE5up) {
object.setAttribute('className',myclass)
} else {
object.setAttribute('class',myclass)
}

Muon
03-10-2003, 12:10 AM
Brilliant, thanks for your help!

Muon
03-10-2003, 12:58 AM
Hey, just discovered that setAttribute won't work for event handlers afterall!

But, I came across the following post in a forum:

http://p2p.wrox.com/archive/javascript/2001-08/22.asp

in which they describe a syntax that will work (with IE at least):

document.all.myElement.onClick=myFunction;

The main limitation seems to be that you can't pass arguments to the function.

Cheers

Graeme Hackston
03-10-2003, 01:52 AM
I just searched around msdn for an example, all I found was this

http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/setattribute.asp

This is just a chunk of code that I know works xbrowser with images. I didn't include where the variables came from but it should give you an idea. I use onclick to test.

Img_class = 'script-img'
New_Img = document.createElement('img')
//New_Img.setAttribute('onclick',"alert(this.id)")
New_Img.setAttribute('id',Img_id)
New_Img.setAttribute('src',Img_src)
New_Img.setAttribute('alt',Img_alt)
New_Img.setAttribute('width',w)
New_Img.setAttribute('height',h)
if (IE5up) {
New_Img.setAttribute('className',Img_class)
} else {
New_Img.setAttribute('class',Img_class)
}
img_box.insertBefore(New_Img, img_box.firstChild);

That puts an image in a div as its first child element.

You can also put event handlers in by writing your html as a string then write it to the page using innerHTML. But that method only allows for innerHTML= or innerHTML+= The DOM method above lets you put it where you like.

Hope that makes sense.

Muon
03-10-2003, 11:27 AM
Thanks Graeme,

that certainly warrants some further investigation on my behalf

brothercake
03-10-2003, 11:41 AM
SetAttribute is very flaky with event handlers - I've only got it to work reliably in Opera


innerHTML is the most cross browser; you can use a replace expression to add the handler, eg:

var tempHTML = someObj.innerHTML;
tempHTML = tempHTML.replace(/<[Dd][Ii][Vv]/,"<div onmouseover='doSomething(this)'");
someObj.innerHTML = tempHTML;


Moz also has addEventListener:

someObj.addEventListener("mouseover",someObj,false);

but afaik this can't pass parameters.

jkd
03-10-2003, 03:51 PM
Originally posted by brothercake
Moz also has addEventListener:

someObj.addEventListener("mouseover",someObj,false);

but afaik this can't pass parameters.

Say what?

EventTarget.addEventListener('eventname', eventHandler, useCapture);

eventHandler will be passed an instance of the event object, which is all you need.

cheesebagpipe
03-10-2003, 10:03 PM
Back to your original Q...

The JS syntax is similar:

object.onclick = function() {
statements
}

...using an function literal. If you want to have the handler evaluated at runtime, use the Function() constructor:

object.onclick = new Function( 'arguments_as_strings' , 'statements_as_strings' );

Doesn't overrule any DOM1+ solutions, naturally. The trick lies in using a function pointer (name minus ()) if you're not passing arguments, and a literal or the constructor if you are. The JS runtime engine 'wraps' the code strings (<element.....onmouseover="statements">) automatically, to make them callable. Don't forget case sensitivity!

Graeme Hackston
03-10-2003, 10:47 PM
Thanks for the info guys. Brothercake, that's the first reg express I've "read". Is it a given that an innerHTML string uses capitals or does that check without an i ?

Muon
03-10-2003, 11:13 PM
thanx cheesebagpipe,

the technique of using the Function constructor has turned out to be ideal for what I wanted to do, as it has enabled me to have my dynamically assigned event handler pass the elements id as a parameter:

object.onclick=new Function ('anotherFunction(this.id)');

cheers guys