Passing arguments to callback function in addEventListener

Discussion in 'Javascript' started by Janus, Jan 8, 2007.

  1. Janus

    Janus Guest

    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
    Janus, Jan 8, 2007
    #1
    1. Advertising

  2. Janus

    VK Guest

    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;
    VK, Jan 8, 2007
    #2
    1. Advertising

  3. Janus

    Janus Guest

    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;
    Janus, Jan 8, 2007
    #3
  4. Janus

    Elegie Guest

    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.
    Elegie, Jan 8, 2007
    #4
  5. Janus

    Janus Guest

    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.
    Janus, Jan 8, 2007
    #5
  6. 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.
    Richard Cornford, Jan 8, 2007
    #6
  7. Janus

    Elegie Guest

    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.
    Elegie, Jan 8, 2007
    #7
  8. 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-Level-3-Events-20060413/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.
    Richard Cornford, Jan 8, 2007
    #8
  9. Janus

    Elegie Guest

    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.
    Elegie, Jan 9, 2007
    #9
  10. Janus

    Paul Guest

    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.
    Paul, Jan 11, 2007
    #10
  11. Paul wrote:
    > 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. ...

    <snip>

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


    Being able to disregard the applicable standard because the context of
    application allows more is not reason for doing so in itself.

    Richard.
    Richard Cornford, Jan 11, 2007
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jmborr
    Replies:
    1
    Views:
    409
    Stargaming
    Nov 3, 2007
  2. Angus
    Replies:
    32
    Views:
    808
    Richard
    Apr 15, 2008
  3. Michael Hill

    addEventListener function in IE

    Michael Hill, Jul 20, 2004, in forum: Javascript
    Replies:
    3
    Views:
    93
    Martin Honnen
    Jul 21, 2004
  4. Erwin Moller
    Replies:
    13
    Views:
    229
    Eric Bednarz
    Jul 26, 2009
  5. William Wallace
    Replies:
    25
    Views:
    958
    David Mark
    Aug 14, 2010
Loading...

Share This Page