PDA

View Full Version : Providing argument to the event listener function



pman
05-03-2007, 01:18 AM
Hi there,

I'm sure a lot of us here had this problem, but I can't seem to find the solution anywhere on the net. I am trying to add an event to an object dynamically like this.


HTML Code:


myObject.addEventListener("click", eventHandler, false) ;
function eventHandler()
{
alert("Hello") ;
}


I know that the above will only work on Geko browsers and for IE, I will have to use attachEvent instead of addEventListener. However, my question is how can I pass one or more arguments to the eventHandler function. From my research, and testing, the function eventHandler will accept only one argument and it is always the event itself. How could I resolve this?

I guess, the javascript clousure could solve this, but I'm still trying to learn it.

Your help is much appreciated. Thanks a lot.
__________________
With Regards

Pman
http://www.pmansLab.com
Reply With Quote

jscheuer1
05-04-2007, 06:52 AM
I always define the function before using it, though that may or may not be important. And, I include the little e to pass the event for browsers that do it that way (basically all but IE):


function eventHandler(e)
{
alert("Hello") ;
}
if ( typeof window.addEventListener != "undefined" )
myObject.addEventListener( "click", eventHandler, false );
else if ( typeof window.attachEvent != "undefined" )
myObject.attachEvent( "onclick", eventHandler );

Now, there may be a way to pass other arguments but, I don't think so. Think of it, the function is being added. So, how would you know what the other arguments would be? You can pass information as properties of the event:


function eventHandler(e)
{
var e=e? e : window.event;
var el=e.target? e.target : e.srcElement;
alert(el.tagName) ;
}

In the above we've grabbed the target (all but IE) or source element (IE) of the event and are alerting its tag name.

Once you have the element in question, you can find all sorts of things if it has them, like its parentNode, its id or class name, whatever. Just make sure it is going to have those things or test if they exist before grabbing them. Like, with id:


if(el.id)
alert(el.id)

You could also pass variables to the function by defining them in some scope that includes the function and then referring to them within the function, but that is a little hard to show in any meaningful way without greater context.

A simple example would be:


var bob='sam';
function eventHandler()
{
alert(bob) ;
}

which would alert the name 'sam'.

Twey
05-04-2007, 09:24 AM
The common solution is to create a new anonymous function passing that argument:
myObject.addEventListener(
"click",
function(e) {
return eventHandler.call(this, e, someArg);
},
false
);That use of .call() will make it almost transparent. The eventHandler() function will receive two arguments, e and someArg, and inside it this will refer to the element as if it were the top-level event handler.

As John says, though, don't forget to include alternatives for browsers that don't support DOM-2 events (like IE). I presume you were just using DOM-2 as an example, but remember that IE's attachEvent() has some limitations: you can only bubble, not capture, and this refers to the global object window, not the element to which you attached the event. Again, you can work around the latter by using .call() and a closure.
I always define the function before using it, though that may or may not be important.It isn't: global named functions are created before the rest of the script is executed.

pman
05-05-2007, 08:34 PM
Yep, the anonymous function solved the problem. This is what I did.



function onLoad()
{
if(myObject.addEventListener)
{
myObject.addEventListener("click", function () {
objOnClickListener("ab", "cd") ; } , false ) ;
}
else
{
myObject.attachEvent("onclick", function () {
objOnClickListener("ab", "cd") ; } ) ;
}
}

function objOnClickListener(arg1, arg2)
{
alert(arg1) ; alert(arg2) ;
}



As John says, though, don't forget to include alternatives for browsers that don't support DOM-2 events (like IE). I presume you were just using DOM-2 as an example, but remember that IE's attachEvent() has some limitations: you can only bubble, not capture, and this refers to the global object window, not the element to which you attached the event. Again, you can work around the latter by using .call() and a closure.

You are right Twey. I think my solution will still suffer from Event bubbling in IE. I don't know how to fix that. Let me know, if you know any. Thanks a lot.

Twey
05-05-2007, 09:22 PM
I think my solution will still suffer from Event bubbling in IE. I don't know how to fix that. Let me know, if you know any.There's no way to "fix" event bubbling, it's just the way IE handles events. It's only worth mentioning because it's different to the standard, so if you do anything that relies upon the order of events, you'll get a nasty surprise when testing in IE.