473,396 Members | 1,861 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Using object methods in addEventListener

When you use addEventListener (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.prototype.call or Function.prototype.apply and passing the
correct this pointer for the context, but how does addEventListener
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
Jul 20 '05 #1
6 17174
jo****@zircon.seattle.wa.us (Joe Kelsey) writes:
When you use addEventListener (or addEvent in IE) to call an object
method, does it call it with the correct this parameter?
Absolutely! Ofcourse, whether that "this" value is the one you expect,
that is another question :).

If you use
node.addEventListener("click",foo.method,false)
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=foo.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.attachEvent("onclick",foo.method)
then the function is executed with this referring to the global (window)
object.
(Tested in IE6)
The ECMAScript reference has a lot to say about the caller using
Function.prototype.call or Function.prototype.apply and passing the
correct this pointer for the context, but how does addEventListener
determine the correct this pointer.
It takes the object the event handler is assigned to, just as if it
was made a property of that object.
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?
IE does that.
I could not find any reference to this in the W3C DOM-2 documentation.


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 "currentTarget" property
of the event. That won't help you for IE, ofcourse.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
Art D'HTML: <URL:http://www.infimum.dk/HTML/randomArtSplit.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 20 '05 #2
Lasse Reichstein Nielsen <lr*@hotpop.com> wrote in message news:<d6**********@hotpop.com>...
jo****@zircon.seattle.wa.us (Joe Kelsey) writes:
When you use addEventListener (or addEvent in IE) to call an object
method, does it call it with the correct this parameter?


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

If you use
node.addEventListener("click",foo.method,false)
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=foo.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.attachEvent("onclick",foo.method)
then the function is executed with this referring to the global (window)
object.
(Tested in IE6)


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="updateSomething (param1, 'param2', this.value);">

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

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

Where node is a previously created element (e.g.,
document.createElement) and addEvent is a suitably defined function to
take care of the difference between addEventListener 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
Jul 20 '05 #3
"Joe Kelsey" <jo****@zircon.seattle.wa.us> wrote in message
news:15**************************@posting.google.c om...
<snip>
var firstPart = "updateSomething (param1, ";
var lastPart = ", this.value);";
addEvent (node, "change", new Function (firstPart +
"'param2'" + lastPart), false);

<snip>

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

Works consistently in current browsers.

If you insist on playing with addEventListener 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.
Jul 20 '05 #4
"Richard Cornford" <ri*****@litotes.demon.co.uk> wrote in message news:<bi**********@hercules.btinternet.com>...
node.onchange = new Function(firstPart +"'param2'" + lastPart);

Works consistently in current browsers.


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
Jul 20 '05 #5
On 27 Aug 2003 15:45:20 -0700, jo****@zircon.seattle.wa.us (Joe
Kelsey) wrote:
"Richard Cornford" <ri*****@litotes.demon.co.uk> wrote in message news:<bi**********@hercules.btinternet.com>...
node.onchange = new Function(firstPart +"'param2'" + lastPart);

Works consistently in current browsers.
Does a standard exist which specifies this behavior or do the browsers
"just do it"?


It's HTML DOM 0 as it's known...
As far as I can tell from reading the DOM documents, no
"onchange" attribute exists in the various Element or Node
descriptions.
No, AddEventListener 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)
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?


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

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

Jul 20 '05 #6
"Joe Kelsey" <jo****@zircon.seattle.wa.us> wrote in message
news:15**************************@posting.google.c om...
"Richard Cornford" <ri*****@litotes.demon.co.uk> wrote in message news:<bi**********@hercules.btinternet.com>...
node.onchange = new Function(firstPart +"'param2'" + lastPart);

Works consistently in current browsers.


Does a standard exist which specifies this behavior or do
the browsers "just do it"?


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.createElement (or before).
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?
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 addEventListener or attachEvent
are used.
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?
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.
Do you just prefer closures?
I like closures. They allow very interesting possibilities (to say the
least).
Something to do with parse-time versus run-time?


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.
Jul 20 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: Oleg Alistratov | last post by:
Is in javascript a method to get object's identifier as string? E.g., may I write function GetName thus, that var v; var s = GetName(v); has led to s == "v"
8
by: David McDivitt | last post by:
We have a massive java application to be made ADA compliant. We want onfocus and onblur events for each text field. The best way seems to be javascript, by cycling through all the nodes recursively...
4
by: Liming | last post by:
Hello all, I have a custom class object with some prototype methods like setKeyDownEvent, etc. The problem is on my webpage, after I instantiate the class, I try to do .addEventLister() to a...
7
by: Ron Goral | last post by:
Hello I am new to creating objects in javascript, so please no flames about my coding style. =) I am trying to create an object that will represent a "div" element as a menu. I have written...
3
by: Greg A | last post by:
What I am unsuccessful at doing is adding the event listener to an object in memory which isn't referencing an HTML element: // DATA OBJECT CONSTRUCTOR function dataObject(id){ // ...
4
by: yumbelie | last post by:
Hi, I've got an issue where I've created a prototype that contains 2 methods, and a few private variables. The first method simply registers the second method to be an event handler for the...
1
by: vunet | last post by:
If I initializer my object as var obj = new SomeObject(); then I have some method inside of the object as: function SomeObject(){ ....... this.showLink = function(){ return "<a...
8
Jezternz
by: Jezternz | last post by:
Ok, I am new to JS OOP, so bare with me. The code is quite large so I will summaries and simplify, to show the piece that isn't working. Ok I have defined a class and then an object with several...
1
by: JWest46088 | last post by:
I'm getting this error when I try to preview my code: TypeError: Error #1009: Cannot access a property or method of a null object reference. at therun4life_fla::MainTimeline/frame1() I don't...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.