Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Javascript (http://www.velocityreviews.com/forums/f68-javascript.html)
-   -   Passing arguments to callback function in addEventListener (http://www.velocityreviews.com/forums/t929112-passing-arguments-to-callback-function-in-addeventlistener.html)

Janus 01-08-2007 11:22 AM

Passing arguments to callback function in addEventListener
 
Hi,

Is there a way to pass arguments to the callback function used inside
an addEventListener?

I see that I can only list the name of the callback function.

For eg, I use this:

var boldLink=document.getElementById('cmtbold');
boldLink.addEventListener("click", rBold, true);

I need the id of boldLink to be accessible from inside the function
rBold()


Thanks in advance.

Deepak


VK 01-08-2007 12:09 PM

Re: Passing arguments to callback function in addEventListener
 

Janus wrote:
> Is there a way to pass arguments to the callback function used inside
> an addEventListener?
> I see that I can only list the name of the callback function.
>
> For eg, I use this:
>
> var boldLink=document.getElementById('cmtbold');
> boldLink.addEventListener("click", rBold, true);
>
> I need the id of boldLink to be accessible from inside the function
> rBold()


So where is the problem? Inside the event handler [this] points to the
element this handler is attached to:

<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">
function rBold() {
window.alert(this.id);
}
function init() {
var boldLink=document.getElementById('cmtbold');
boldLink.addEventListener("click", rBold, true);
}
window.onload = init;
</script>
</head>
<body>
<p><a href="/" id="cmtbold">Click me</a></p>
</body>
</html>

Please note that IE doesn't support addEventListener and traditionally
used attachEvent method is made for all other purposes so rather
troublesome as a substitution for addEventListener.

addEventListener should be used only if you are planning to have one
event listened by several objects at once. Otherwise use the
conventional intrinsic event handler:

boldLink.onclick = rBold;


Janus 01-08-2007 12:15 PM

Re: Passing arguments to callback function in addEventListener
 
Thanks VK.
I cannot do without addEventListener because I am creating a
Greasemonkey user script.
The intrinsic event handler won't work with GM.

One more question:
Is there a way to pass other types of parameters? Like an integer?


Regards,
Deepak

VK wrote:
> Janus wrote:
> > Is there a way to pass arguments to the callback function used inside
> > an addEventListener?
> > I see that I can only list the name of the callback function.
> >
> > For eg, I use this:
> >
> > var boldLink=document.getElementById('cmtbold');
> > boldLink.addEventListener("click", rBold, true);
> >
> > I need the id of boldLink to be accessible from inside the function
> > rBold()

>
> So where is the problem? Inside the event handler [this] points to the
> element this handler is attached to:
>
> <html>
> <head>
> <title>Untitled Document</title>
> <meta http-equiv="Content-Type"
> content="text/html; charset=iso-8859-1">
> <script type="text/javascript">
> function rBold() {
> window.alert(this.id);
> }
> function init() {
> var boldLink=document.getElementById('cmtbold');
> boldLink.addEventListener("click", rBold, true);
> }
> window.onload = init;
> </script>
> </head>
> <body>
> <p><a href="/" id="cmtbold">Click me</a></p>
> </body>
> </html>
>
> Please note that IE doesn't support addEventListener and traditionally
> used attachEvent method is made for all other purposes so rather
> troublesome as a substitution for addEventListener.
>
> addEventListener should be used only if you are planning to have one
> event listened by several objects at once. Otherwise use the
> conventional intrinsic event handler:
>
> boldLink.onclick = rBold;



Elegie 01-08-2007 01:14 PM

Re: Passing arguments to callback function in addEventListener
 
Janus wrote:

Hello,

> Is there a way to pass arguments to the callback function used inside
> an addEventListener?


Yes, but not directly. Instead of 'passing' the arguments, you should
rather think about making them accessible to the handler. Many patterns
are available.

[1] Make your variable available in the handler function scope chain, so
that it can reach it and use it. For instance, you could use some global
variable.

Ex:

---
var foo="Hello, World!";
obj.addEventListener(
"click",
function handler(evt){
alert(foo);
},
false
);
---

[2] Following the same idea, but being more precise, enclose your
handler into some local function expression, which will know the value
of the variable (or a way to retrieve it). You avoid namespace
pollution, at a cost of a function expression.

Ex:

---
obj.addEventListener(
"click",
(function(foo){
return function (evt){
alert(foo);
}
})("Hello, World!"),
false
);
---

[3] Add the property directly on the event target (as an expando
property), then you'll be able to retrieve it through the 'this' value
in your event handler.

Ex:
---
obj.foo="Hello, World!";
obj.addEventListener(
"click",
function handler(evt){
alert(this.foo);
},
false
);
---

[4] Instead of passing the handler directly, pass some object
implementing the EventListener interface. The 'this' value will now
point to this object and not to the EventTarget anymore. You can then
define your expando properties on this object, like in [3]. Note that
the 'this' value resolution is not documented, so it may not be working
on some browsers (it's okay in Firefox and Opera 9, though).

Ex:

---
obj.addEventListener(
"click",
{foo:"Hello, World!", handleEvent:function(evt){alert(this.foo)}},
false
);
---


HTH,
Elegie.

Janus 01-08-2007 01:22 PM

Re: Passing arguments to callback function in addEventListener
 
Thanks a lot, Elegie.


Elegie wrote:
> Janus wrote:
>
> Hello,
>
> > Is there a way to pass arguments to the callback function used inside
> > an addEventListener?

>
> Yes, but not directly. Instead of 'passing' the arguments, you should
> rather think about making them accessible to the handler. Many patterns
> are available.
>
> [1] Make your variable available in the handler function scope chain, so
> that it can reach it and use it. For instance, you could use some global
> variable.
>
> Ex:
>
> ---
> var foo="Hello, World!";
> obj.addEventListener(
> "click",
> function handler(evt){
> alert(foo);
> },
> false
> );
> ---
>
> [2] Following the same idea, but being more precise, enclose your
> handler into some local function expression, which will know the value
> of the variable (or a way to retrieve it). You avoid namespace
> pollution, at a cost of a function expression.
>
> Ex:
>
> ---
> obj.addEventListener(
> "click",
> (function(foo){
> return function (evt){
> alert(foo);
> }
> })("Hello, World!"),
> false
> );
> ---
>
> [3] Add the property directly on the event target (as an expando
> property), then you'll be able to retrieve it through the 'this' value
> in your event handler.
>
> Ex:
> ---
> obj.foo="Hello, World!";
> obj.addEventListener(
> "click",
> function handler(evt){
> alert(this.foo);
> },
> false
> );
> ---
>
> [4] Instead of passing the handler directly, pass some object
> implementing the EventListener interface. The 'this' value will now
> point to this object and not to the EventTarget anymore. You can then
> define your expando properties on this object, like in [3]. Note that
> the 'this' value resolution is not documented, so it may not be working
> on some browsers (it's okay in Firefox and Opera 9, though).
>
> Ex:
>
> ---
> obj.addEventListener(
> "click",
> {foo:"Hello, World!", handleEvent:function(evt){alert(this.foo)}},
> false
> );
> ---
>
>
> HTH,
> Elegie.



Richard Cornford 01-08-2007 02:13 PM

Re: Passing arguments to callback function in addEventListener
 
Elegie wrote:
<snip>
> [4] Instead of passing the handler directly, pass some object
> implementing the EventListener interface.


That is very risky in javascript. The W3C ECMAScript bindings for the
EventListener interface effectively say that any _function_ is an
EventListener. The fact that some browsers also allow an object that
resembles a Java EventListener to be used (and object with specific
methods) is a non-specified extension.

> The 'this' value will now
> point to this object and not to the EventTarget anymore. You can then
> define your expando properties on this object, like in [3]. Note that
> the 'this' value resolution is not documented, so it may not be working
> on some browsers (it's okay in Firefox and Opera 9, though).

<snip>

There should be no expectation of this working anywhere, so finding two
browsers where it does might be the full extent of support.

Richard.


Elegie 01-08-2007 03:44 PM

Re: Passing arguments to callback function in addEventListener
 
Richard Cornford wrote:

>> [4] Instead of passing the handler directly, pass some object
>> implementing the EventListener interface.

>
> That is very risky in javascript. The W3C ECMAScript bindings for the
> EventListener interface effectively say that any _function_ is an
> EventListener. The fact that some browsers also allow an object that
> resembles a Java EventListener to be used (and object with specific
> methods) is a non-specified extension.


Richard, the specification would then be poorly worded. The bindings
page states the existence of one "EventListener Function", how could you
tell it does not refer to the handleEvent function? All the more that
the bindings page mentions, in the EventTarget description, "objects
that implements the EventListener interface", and not "EventListener
Functions".

<URL:http://www.w3.org/TR/2006/WD-DOM-Level-3-Events-20060413/ecma-script-binding.html>

To me it would seem as if the direct use of the function would _not_ be
standard, but rather some implicitly accepted exception due to
historical reasons (for instance as the consequence of assigning
functions to regular HTML event attributes).

Of course, I would not be encouraging the use of the EventListener
interface in ECMAScript programs for that very reason, all the more that
the risk of it being broken in further versions of the environment would
probably not be the worth of using the construct. However, the OP
working in some identified environment (a GreaseMonkey script), I felt
that it would be relevant and interesting to mention the possibility
(especially for the particular 'this' value handling).

> There should be no expectation of this working anywhere, so finding two
> browsers where it does might be the full extent of support.


When I first read the specification, I had the expectation of it working
_anywhere_ in compliant user agents! Could the use of all other
interfaces be derived from the specification, except for the
EventListener interface?

By the way I do not have lots of browsers on this station, if you would
happen to know about some browsers supporting the DOM Event Model and
not allowing the use of EventListener as described, please let me know.


Regards,
Elegie.

Richard Cornford 01-08-2007 11:02 PM

Re: Passing arguments to callback function in addEventListener
 
Elegie wrote:
> Richard Cornford wrote:
>
>>> [4] Instead of passing the handler directly, pass some object
>>> implementing the EventListener interface.

>>
>> That is very risky in javascript. The W3C ECMAScript bindings
>> for the EventListener interface effectively say that any
>> _function_ is an EventListener. The fact that some browsers also
>> allow an object that resembles a Java EventListener to be used
>> (and object with specific methods) is a non-specified extension.

>
> Richard, the specification would then be poorly worded.


That may be true, though maybe only to the extent that trying to
misinterpret it remains too practical.

Previous versions were certainly less misleadingly worded, for example
the ECMAScript Binding for the November 2000 version of DOM Level 2
events describes EventListener as:-

| Object EventListener
| This is an ECMAScript function reference. This method has no
| return value. The parameter is a Event object.

and - EventTarget - as:-

| Object EventTarget
| The EventTarget object has the following methods:
| addEventListener(type, listener, useCapture)
| This method has no return value.
| The type parameter is of type String.
| The listener parameter is a EventListener object.
| The useCapture parameter is of type Boolean.
| removeEventListener(type, listener, useCapture)
| This method has no return value.
| The type parameter is of type String.
| The listener parameter is a EventListener object.
| The useCapture parameter is of type Boolean.
| dispatchEvent(evt)
| This method returns a Boolean.
| The evt parameter is a Event object.
| This method can raise a EventException object.

The version you cite has changed the wording of the bindings document,
but does not appear to have changed its intended meaning.

> The bindings page states the existence of one
> "EventListener Function",


And that is the _only_ definition of what an EventListener is in an
ECMAScript implementation: it is a function (that accepts an event
object as an argument and has no (explicit) return value).

> how could you tell it does not refer to the handleEvent
> function?


Compare the definition of EventListener with the definitions of
interfaces that include methods and properties. If EventListener was
intended to be anything but a function object then the bindings could
easily have expressed that.

> All the more that the bindings page mentions, in the EventTarget
> description, "objects that implements the EventListener interface",
> and not "EventListener Functions".


Maybe not the best of expressions, but a function is an object and
implementing the " EventListener interface" involves being a function
(that accepts an event object as an argument and has no (explicit)
return value).

>

<URL:http://www.w3.org/TR/2006/WD-DOM-Lev...413/ecma-scrip
t-binding.html>
>
> To me it would seem as if the direct use of the function would
> _not_ be standard, but rather some implicitly accepted exception
> due to historical reasons (for instance as the consequence of
> assigning functions to regular HTML event attributes).


If that were the case I would expect to see the definition of
EventListener resemble EventTarget or Event, and explicitly state that
the interface has a method and the arguments and return values for that
method.

> Of course, I would not be encouraging the use of the
> EventListener interface in ECMAScript programs


If the EventListener interface is just a function object they why not?

<snip>
> By the way I do not have lots of browsers on this station,
> if you would happen to know about some browsers supporting
> the DOM Event Model and not allowing the use of EventListener
> as described, please let me know.


The last time we discussed this subject here only Mozilla/Gecko browser
supported a Java-style version of EventListener. It looks like Opera
have seen it as expedient to add such support, but I don't know whether
Konqueror, Safari, NetFront, IceBrowser, etc. will have done so.

Richard.



Elegie 01-09-2007 12:52 AM

Re: Passing arguments to callback function in addEventListener
 
Richard Cornford wrote:

<snip>

> Previous versions were certainly less misleadingly worded, for example
> the ECMAScript Binding for the November 2000 version of DOM Level 2
> events describes EventListener as:-


<snip>

Granted, that description was much clearer, say, accurate.

> The version you cite has changed the wording of the bindings document,
> but does not appear to have changed its intended meaning.


Well, I am not familiar with W3C DOM orientations so wouldn't be able to
discuss it (and that would be off-topic), however I have to say that,
should I consider all versions of the specification, it would certainly
appear that its intended meaning may have changed as well!

Unfortunately, the change of wording has happened in Feb. 2002, and the
changes notes simply state: "This page needs update".

<URL:http://www.w3.org/TR/2002/WD-DOM-Level-3-Events-20020208/changes.html>

I have however found some discussions where they seem to have accepted
that EventListener could be Functions or Objects implementing the
EventListener interfaces. The following expresses their conclusion about
how the 'this' value should then be determined.

<URL:http://lists.w3.org/Archives/Public/public-webapi/2006Mar/0122.html>

Also, they have even been thinking about adding a handleEvent function
to the EventListener, stating that it would be referencing itself -
probably some kind of (awkward) compatibility bridge.

<URL:http://lists.w3.org/Archives/Public/public-webapi/2006Apr/0359.html>

>> how could you tell it does not refer to the handleEvent
>> function?

>
> Compare the definition of EventListener with the definitions of
> interfaces that include methods and properties. If EventListener was
> intended to be anything but a function object then the bindings could
> easily have expressed that.


Agreed, however on the other hand... would it have not been "easy" as
well to state that the EventListener *is* an ECMAScript function? They
did not do that.

>> To me it would seem as if the direct use of the function would
>> _not_ be standard, but rather some implicitly accepted exception
>> due to historical reasons (for instance as the consequence of
>> assigning functions to regular HTML event attributes).

>
> If that were the case I would expect to see the definition of
> EventListener resemble EventTarget or Event, and explicitly state that
> the interface has a method and the arguments and return values for that
> method.


Well in the actual specification the definition of EventListener is
similar to the EventTarget or Event ones, the bindings page simply fails
to properly mimic the change? Or even worse, does not do it because this
could mean some change in actual (W3C) implementations? :)

However my calling that an exception was, in the light of the link you
have provided, clearly an error : it was indeed the norm six years ago.
However I feel it is much more questionable now.

>> Of course, I would not be encouraging the use of the
>> EventListener interface in ECMAScript programs

>
> If the EventListener interface is just a function object they why not?


This specification, as of its last version (proposed six years after
than the one you cite), does not make it clear to me. I'd therefore
recommend the Function approach, however not arguing the respect of a
specification, but rather some back-compatibility aspect.

> The last time we discussed this subject here only Mozilla/Gecko browser
> supported a Java-style version of EventListener. It looks like Opera
> have seen it as expedient to add such support, but I don't know whether
> Konqueror, Safari, NetFront, IceBrowser, etc. will have done so.


Okay, thanks for the info.


Regards,
Elegie.

Paul 01-11-2007 02:16 AM

Re: Passing arguments to callback function in addEventListener
 

Richard Cornford wrote:
> Elegie wrote:
> <snip>
> > [4] Instead of passing the handler directly, pass some object
> > implementing the EventListener interface.

>
> That is very risky in javascript. The W3C ECMAScript bindings for the
> EventListener interface effectively say that any _function_ is an
> EventListener. The fact that some browsers also allow an object that
> resembles a Java EventListener to be used (and object with specific
> methods) is a non-specified extension.
>
> > The 'this' value will now
> > point to this object and not to the EventTarget anymore. You can then
> > define your expando properties on this object, like in [3]. Note that
> > the 'this' value resolution is not documented, so it may not be working
> > on some browsers (it's okay in Firefox and Opera 9, though).

> <snip>
>
> There should be no expectation of this working anywhere, so finding two
> browsers where it does might be the full extent of support.
>
> Richard.


The OP mentioned he was developing a greasemonkey script for firefox.



All times are GMT. The time now is 08:49 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.