Using object methods in addEventListener

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Joe Kelsey

    Using object methods in addEventListener

    When you use addEventListene r (or addEvent in IE) to call an object
    method, does it call it with the correct this parameter?

    The ECMAScript reference has a lot to say about the caller using
    Function.protot ype.call or Function.protot ype.apply and passing the
    correct this pointer for the context, but how does addEventListene r
    determine the correct this pointer. Or does it just punt and pass the
    global context, thus making it impossible to refer to the object this
    in an object method used as an event listener?

    I could not find any reference to this in the W3C DOM-2 documentation.

    /Joe
  • Lasse Reichstein Nielsen

    #2
    Re: Using object methods in addEventListene r

    joe-gg@zircon.seatt le.wa.us (Joe Kelsey) writes:
    [color=blue]
    > When you use addEventListene r (or addEvent in IE) to call an object
    > method, does it call it with the correct this parameter?[/color]

    Absolutely! Ofcourse, whether that "this" value is the one you expect,
    that is another question :).

    If you use
    node.addEventLi stener("click", foo.method,fals e)
    and then click on the node, the function referred to by "foo.method "
    is executed with "this" referring to "node". Just as if you had
    used
    node.onclick=fo o.method;
    It never refers to "foo", which some might consider the correct value
    of "this".
    (Tested in Opera 7 and Mozilla FB 0.6)

    If you use the IE version:
    node.attachEven t("onclick",foo .method)
    then the function is executed with this referring to the global (window)
    object.
    (Tested in IE6)
    [color=blue]
    > The ECMAScript reference has a lot to say about the caller using
    > Function.protot ype.call or Function.protot ype.apply and passing the
    > correct this pointer for the context, but how does addEventListene r
    > determine the correct this pointer.[/color]

    It takes the object the event handler is assigned to, just as if it
    was made a property of that object.
    [color=blue]
    > Or does it just punt and pass the global context, thus making it
    > impossible to refer to the object this in an object method used as
    > an event listener?[/color]

    IE does that.
    [color=blue]
    > I could not find any reference to this in the W3C DOM-2 documentation.[/color]

    That would be in W3C DOM 2 Events, and it doesn't say that. The
    specification of an eventListener is an interface (i.e., an object
    description) that contains a function to be called. That is because
    it is written for languages that doesn't have first class functions,
    like Javascript does. In such a language, the "this" value would be
    the wrapper object for the function.
    In Javascript we just pass the function itself, so it doesn't have
    an obvious base object. Smart people made addEventHandler works as
    close to assigning directly to the "onclick" property, but it is
    not a requirement. IE didn't.

    The DOM 2 Event specification gives another way of accessing the
    node that an eventListener is assigned to: the "currentTar get" property
    of the event. That won't help you for IE, ofcourse.

    /L
    --
    Lasse Reichstein Nielsen - lrn@hotpop.com
    Art D'HTML: <URL:http://www.infimum.dk/HTML/randomArtSplit. html>
    'Faith without judgement merely degrades the spirit divine.'

    Comment

    • Joe Kelsey

      #3
      Re: Using object methods in addEventListene r

      Lasse Reichstein Nielsen <lrn@hotpop.com > wrote in message news:<d6esdth8. fsf@hotpop.com> ...[color=blue]
      > joe-gg@zircon.seatt le.wa.us (Joe Kelsey) writes:
      >[color=green]
      > > When you use addEventListene r (or addEvent in IE) to call an object
      > > method, does it call it with the correct this parameter?[/color]
      >
      > Absolutely! Ofcourse, whether that "this" value is the one you expect,
      > that is another question :).
      >
      > If you use
      > node.addEventLi stener("click", foo.method,fals e)
      > and then click on the node, the function referred to by "foo.method "
      > is executed with "this" referring to "node". Just as if you had
      > used
      > node.onclick=fo o.method;
      > It never refers to "foo", which some might consider the correct value
      > of "this".
      > (Tested in Opera 7 and Mozilla FB 0.6)
      >
      > If you use the IE version:
      > node.attachEven t("onclick",foo .method)
      > then the function is executed with this referring to the global (window)
      > object.
      > (Tested in IE6)[/color]

      So attachEvent in IE does something completely different from
      specifying code directly in onclick="" in HTML? I mean I can put this
      directly into the onclick HTML spec

      <input blah...blah...
      onclick="update Something (param1, 'param2', this.value);">

      and expect that this.value refers to the input node. But if I
      construct the Function inside javascript

      var firstPart = "updateSomethin g (param1, ";
      var lastPart = ", this.value);";
      addEvent (node, "change", new Function (firstPart + "'param2'" +
      lastPart), false);

      Where node is a previously created element (e.g.,
      document.create Element) and addEvent is a suitably defined function to
      take care of the difference between addEventListene r and attachEvent,
      then this.value will not work in IE?

      If IE really supplies the global window context as this to the event
      function, then it seems impossible to emulate the HTML behavior from
      javascript.

      I want to move some bizarre use of <script> as template html into
      javascript. That means creating dynamic elements that include
      onchange handlers. All of the handlers basically look the same except
      for the 'param2' value.

      /Joe

      Comment

      • Richard Cornford

        #4
        Re: Using object methods in addEventListene r

        "Joe Kelsey" <joe-gg@zircon.seatt le.wa.us> wrote in message
        news:151bebc0.0 308270945.7234c 197@posting.goo gle.com...
        <snip>[color=blue]
        >var firstPart = "updateSomethin g (param1, ";
        >var lastPart = ", this.value);";
        >addEvent (node, "change", new Function (firstPart +
        >"'param2'" + lastPart), false);[/color]
        <snip>

        node.onchange = new Function(firstP art +"'param2'" + lastPart);

        Works consistently in current browsers.

        If you insist on playing with addEventListene r and attachEvent then
        closure based solutions can be applied to rectify IE's deficiencies (and
        maybe include param2 in the closure and avoid the need to explicitly
        call the Function constructor to create a new function for each event
        handler).

        Richard.


        Comment

        • Joe Kelsey

          #5
          Re: Using object methods in addEventListene r

          "Richard Cornford" <richard@litote s.demon.co.uk> wrote in message news:<biisig$26 3$1@hercules.bt internet.com>.. .[color=blue]
          > node.onchange = new Function(firstP art +"'param2'" + lastPart);
          >
          > Works consistently in current browsers.[/color]

          Does a standard exist which specifies this behavior or do the browsers
          "just do it"? As far as I can tell from reading the DOM documents, no
          "onchange" attribute exists in the various Element or Node
          descriptions. Have I missed something?

          Also, why prefer a closure using a function expression to creating a
          new Function object? Does creating a new Function object involve some
          sort of penalty that function expressions do not have? Do you just
          prefer closures? Something to do with parse-time versus run-time?

          /Joe

          Comment

          • Jim Ley

            #6
            Re: Using object methods in addEventListene r

            On 27 Aug 2003 15:45:20 -0700, joe-gg@zircon.seatt le.wa.us (Joe
            Kelsey) wrote:
            [color=blue]
            >"Richard Cornford" <richard@litote s.demon.co.uk> wrote in message news:<biisig$26 3$1@hercules.bt internet.com>.. .[color=green]
            >> node.onchange = new Function(firstP art +"'param2'" + lastPart);
            >>
            >> Works consistently in current browsers.[/color]
            >
            >Does a standard exist which specifies this behavior or do the browsers
            >"just do it"?[/color]

            It's HTML DOM 0 as it's known...
            [color=blue]
            > As far as I can tell from reading the DOM documents, no
            >"onchange" attribute exists in the various Element or Node
            >descriptions .[/color]

            No, AddEventListene r etc. is the appropriate method, but DOM Level 0
            is more sensible now (you use "document" right, that's not in a
            standard either just DOM 0)
            [color=blue]
            >Also, why prefer a closure using a function expression to creating a
            >new Function object? Does creating a new Function object involve some
            >sort of penalty that function expressions do not have?[/color]

            It's very expensive, it's just like eval...

            Jim.
            --
            comp.lang.javas cript FAQ - http://jibbering.com/faq/

            Comment

            • Richard Cornford

              #7
              Re: Using object methods in addEventListene r

              "Joe Kelsey" <joe-gg@zircon.seatt le.wa.us> wrote in message
              news:151bebc0.0 308271445.57887 ecd@posting.goo gle.com...[color=blue]
              > "Richard Cornford" <richard@litote s.demon.co.uk> wrote in message[/color]
              news:<biisig$26 3$1@hercules.bt internet.com>.. .[color=blue][color=green]
              > > node.onchange = new Function(firstP art +"'param2'" + lastPart);
              > >
              > > Works consistently in current browsers.[/color]
              >
              >Does a standard exist which specifies this behavior or do
              >the browsers "just do it"?[/color]

              They just do it, and have been doing it for so long that no browser
              manufacturer would dare drop the feature for fear of producing a browser
              that looked like it did not work with much of the web.

              The number of events supported on different elements in the DOM varies,
              with IE supporting the greatest number of events through defined
              properties of the elements and Netscape 4 supporting just a limited
              number of events (and having fewest accessible elements anyway). Though
              Netscape 4 support is not relevant as it has already failed at
              document.create Element (or before).
              [color=blue]
              >As far as I can tell from reading the DOM documents, no
              >"onchange" attribute exists in the various Element or Node
              >descriptions . Have I missed something?[/color]

              I used the onchange property because you were passing the string
              "change" as the second parameter to your - addEvent - function, so I
              assumed that you were interested in setting onchange handlers and would
              not be attempting to use them on elements that do not support onchange
              attributes. I haven't attempted to confirm this but I would suspect
              that, for any Element type, the range of event handlers that can be set
              as properties of the element corresponds exactly with the range of
              events that can trigger functions when addEventListene r or attachEvent
              are used.
              [color=blue]
              >Also, why prefer a closure using a function expression to
              >creating a new Function object?
              >Does creating a new Function object involve some
              >sort of penalty that function expressions do not have?[/color]

              Why not? They both will fail under their own individual and very limited
              set of circumstances. For that reason the Function constructor might be
              preferred as its failure can be ascertained by testing before it
              happens, allowing more controlled fall-back. While when inner functions
              fail it is because the JavaScript version is so old that they are not
              supported, becoming syntax errors and killing off script execution for
              the entire page, but we are talking JavaScript version 1.0 (and maybe
              1.1), so not something that needs to be worried about these days.

              Closures are not without there drawbacks, they are among the easiest
              ways of creating the circular JavaScript object <-> DOM element
              references that induce the memory leak problem in IE. But can usually be
              coded to avoid that problem, and if not additional code can be used as a
              solution to that problem.

              In this case I mentioned closures because they would offer the option of
              addressing two conditions at once, the scope resolution of the function
              in IE and the problem of passing a different - param2 - to each
              function.

              The Function constructor carries the penalty that its function body is
              parsed on each invocation of the constructor. Authors used to IE will
              often be expecting excellent performance from the eval function and the
              Function constructor. Unfortunately both experience a wide range of
              performances in different implementations , with some implementations
              being up to 6 times slower than IE under most circumstances and, with
              some code structures, up to 400 times slower (but that is very much the
              exception).

              Ironically one place where the Function constructor offers manifest
              benefits is performance critical code that requires the repeated
              execution of the same function (such as sorting a very big array of
              objects using a custom comparison function) where the function body will
              have to use parameters/identifiers/indexes unknown until the execution
              of the script. A closure could do it but the Function constructor could
              create a function hard-coded to the task and as a result as efficient as
              it could be.
              [color=blue]
              >Do you just prefer closures?[/color]

              I like closures. They allow very interesting possibilities (to say the
              least).
              [color=blue]
              >Something to do with parse-time versus run-time?[/color]

              That could be a factor.

              In the end each has its place, I just think that the scope for the
              appropriate application of the Function constructor is much more limited
              than for the appropriate application of closures.

              Richard.


              Comment

              Working...