'this', event handlers, and namespaces | | |
Hi,
Consider the following simplified code in which Foo is used as a
'namespace':
var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: function(e) {
this.doAlert();
}
}
document.addEventListener('keydown', Foo.doAlert, false);
This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached the
event handler to. I know I could just replace 'this' with "Foo.' but
my understanding is that I take a performance hit every time I make
such a global reference. And, since I'm developing a large web
application in Javascript, I'd like to avoid unnecessary performance
hits when possible.
Anyone know what is the accepted standard of what to do in this case?
Thanks!
Jeff | | | | re: 'this', event handlers, and namespaces
On May 16, 9:27 am, Jeff Bigham <jeffrey.big...@gmail.comwrote: Quote:
Hi,
>
Consider the following simplified code in which Foo is used as a
'namespace':
>
var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: function(e) {
this.doAlert();
}
>
}
>
document.addEventListener('keydown', Foo.doAlert, false);
>
This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached the
event handler to. I know I could just replace 'this' with "Foo.' but
my understanding is that I take a performance hit every time I make
such a global reference. And, since I'm developing a large web
application in Javascript, I'd like to avoid unnecessary performance
hits when possible.
>
Anyone know what is the accepted standard of what to do in this case?
Try this thread:
Subject: pseudo-namespacing in JavaScript
<URL: http://groups.google.com.au/group/co...45e485506c4a92
--
Rob | | | | re: 'this', event handlers, and namespaces
On May 15, 7:27*pm, Jeff Bigham <jeffrey.big...@gmail.comwrote: Quote:
Hi,
>
Consider the following simplified code in which Foo is used as a
'namespace':
>
var Foo = {
* doAlert: function() {
* * alert('hello');
* },
* myEventHandler: function(e) {
* * this.doAlert();
* }
>
}
>
document.addEventListener('keydown', Foo.doAlert, false);
>
This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached the
event handler to. *I know I could just replace 'this' with "Foo.' but
my understanding is that I take a performance hit every time I make
such a global reference. *And, since I'm developing a large web
application in Javascript, I'd like to avoid unnecessary performance
hits when possible.
>
Anyone know what is the accepted standard of what to do in this case?
>
Thanks!
Jeff
I don't know if it's the accepted standard of what to do, but you
could do something like:
var Foo = {
* doAlert: function() {
* * alert('hello');
* },
* myEventHandler: (function(t) {
that = t;
return function(e) {
* * that.doAlert();
};
})(this)
}
I don't think this would be avoiding a performance hit though, and you
probably shouldn't listen to my advice as I'm still a bit green on
javascript. Additionally, I think the proper solution depends on what
exactly you're trying to do. | | | | re: 'this', event handlers, and namespaces
Jeff Bigham wrote: Quote:
Consider the following simplified code in which Foo is used as a
'namespace':
>
var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: function(e) {
this.doAlert();
}
}
>
document.addEventListener('keydown', Foo.doAlert, false);
Probably you meant to write
document.addEventListener('keydown', Foo.myEventHandler, false);
instead, as there is no `this' in Foo.doAlert(). Quote:
This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached
the event handler to.
_added_ event _listener_ to
This is a FAQ, and the solution is simple:
document.addEventListener(
'keydown',
function(e) { Foo.myEventHandler(e) },
false);
That said, by convention only names of properties that refer to
constructors, and identifiers of constant primitive values, should begin
with a capital letter. Quote:
I know I could just replace 'this' with "Foo.' but my understanding
is that I take a performance hit every time I make such a global reference.
That is correct, as no identifier resolution is required for the `this'
value of the execution context. However, the evaluation loop would be very
short; the main issue here is maintainability: You really do not want to do
search and replace when you have to rename `Foo' (and you should do that). Quote:
And, since I'm developing a large web application in Javascript, I'd
like to avoid unnecessary performance hits when possible.
Good thinking, though. Quote:
Anyone know what is the accepted standard of what to do in this case?
There is no accepted standard about it, only common sense guided by the text
of the ECMAScript Specification and by the reality of its implementations.
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann | | | | re: 'this', event handlers, and namespaces
jdd wrote: Quote:
On May 15, 7:27 pm, Jeff Bigham <jeffrey.big...@gmail.comwrote: Quote:
>Consider the following simplified code in which Foo is used as a
>'namespace':
>>
>var Foo = {
> doAlert: function() {
> alert('hello');
> },
> myEventHandler: function(e) {
> this.doAlert();
> }
>}
>>
>document.addEventListener('keydown', Foo.doAlert, false);
>>
>This gives me an error because when responding to the event, the
>object 'this' is the document because that's what I've attached the
>event handler to. [...]
>>
>Anyone know what is the accepted standard of what to do in this case?
>
I don't know if it's the accepted standard of what to do, but you
could do something like:
>
var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: (function(t) {
that = t;
return function(e) {
that.doAlert();
};
})(this)
}
This code does not address the problem at all. In the above scenario, the
`myEventHandler' property would be assigned a reference to a Function object
that calls the doAlert() method of the *Global Object* (or the object
referenced by the `that' property of an object in the scope chain, see
below) instead of the object referred to by `Foo'. A TypeError exception on
event is likely as the Global Object (or that object) is unlikely to have a
method of that name. It is semantically equal to
that = this;
var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: function(e) {
that.doAlert();
};
};
Also, the undeclared `that' identifier is inherently error-prone.
Please trim your quotes as recommended e.g. in the FAQ Notes.
PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm> | | | | re: 'this', event handlers, and namespaces
On May 15, 10:14*pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote: Quote:
This code does not address the problem at all. . . *
You are correct, thanks for the explanation. | | | | re: 'this', event handlers, and namespaces
On May 16, 1:27*am, Jeff Bigham <jeffrey.big...@gmail.comwrote: Quote:
Hi,
>
Consider the following simplified code in which Foo is used as a
'namespace':
>
var Foo = {
* doAlert: function() {
* * alert('hello');
* },
* myEventHandler: function(e) {
* * this.doAlert();
* }
>
}
>
document.addEventListener('keydown', Foo.doAlert, false);
>
This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached the
event handler to. *I know I could just replace 'this' with "Foo.' but
my understanding is that I take a performance hit every time I make
such a global reference. *And, since I'm developing a large web
application in Javascript, I'd like to avoid unnecessary performance
hits when possible.
>
Anyone know what is the accepted standard of what to do in this case?
>
Thanks!
Jeff
<html lang="en"><head>
<title>untitled</title></head><body>
<script>
var c= ": No closure";
(function () {
var d, e, c= ": anon f closure !";;
var y= function (p) { return document.createElement(p) };
var z= function (p) {
document.body.appendChild(y('br'));
return document.body.appendChild(p);
};
var x= function (p) { (z(y('text'))).innerHTML= p };
var foo= function (e) {
var c= ": foo closure !";
var me= arguments.callee;
me.doAlert= function() { x(this.src+': onClick'+c) };
var doAlert= function() { x(this.src+': onMouseUp'+c) };
//function object method : foo.doAlert()
e.onclick= me.doAlert;
//foo local var:
e.onmouseup= doAlert;
//anonymous function:
e.onmouseover= function () { x(this.src+': onMouseOver'+c) };
return e;
};
foo.too= function () { x(this.src+': onMouseOut'+c) };
(e= foo(z(y('img')))).src="http://tinyurl.com/6nhepj"
//anonimous function object method 2:
e.onmouseout= foo.too;
(d=z(y('img'))).src="http://tinyurl.com/5ehxv5"
//anonimous function object method 2:
d.onmouseout= foo.too;
d.onmouseover= e.onmouseover;
})();
</script></body></html> | | | | re: 'this', event handlers, and namespaces
On May 16, 1:27*am, Jeff Bigham <jeffrey.big...@gmail.comwrote: Quote:
Hi,
>
Consider the following simplified code in which Foo is used as a
'namespace':
>
var Foo = {
* doAlert: function() {
* * alert('hello');
* },
* myEventHandler: function(e) {
* * this.doAlert();
* }
>
}
>
document.addEventListener('keydown', Foo.doAlert, false);
>
This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached the
event handler to. *I know I could just replace 'this' with "Foo.' but
my understanding is that I take a performance hit every time I make
such a global reference. *And, since I'm developing a large web
application in Javascript, I'd like to avoid unnecessary performance
hits when possible.
>
Anyone know what is the accepted standard of what to do in this case?
>
Thanks!
Jeff
<html lang="en"><head>
<title>untitled</title></head><body>
<script>
var c= ": No closure";
(function () {
var d, e, c= ": anon f closure !";;
var y= function (p) { return document.createElement(p) };
var z= function (p) { return document.body.appendChild(p) };
var x= function (p) {
z(y('br'));
(z(y('text'))).innerHTML= p;
};
var foo= function (e) {
var c= ": foo closure !";
var me= arguments.callee;
me.doAlert= function() { x(this.src+': onClick'+c) };
var doAlert= function() { x(this.src+': onMouseUp'+c) };
//function object method : foo.doAlert()
e.onclick= me.doAlert;
//foo local var:
e.onmouseup= doAlert;
//anonymous function:
e.onmouseover= function () { x(this.src+': onMouseOver'+c) };
return e;
};
foo.too= function () { x(this.src+': onMouseOut'+c) };
(e= foo(z(y('img')))).src="http://tinyurl.com/6nhepj"
//anonimous function object method 2:
e.onmouseout= foo.too;
(d=z(y('img'))).src="http://tinyurl.com/5ehxv5"
//anonimous function object method 2:
d.onmouseout= function () { x(this.src+': onMouseOut'+c) };
d.onmouseover= function () { x(this.src+': onMouseOver'+c) };
d.onclick= function() { x(this.src+': onClick'+c) };
d.onmouseup= function () { x(this.src+': onMouseUp'+c) };
(d=z(y('img'))).src="http://tinyurl.com/5j84u6"
//anonimous function object method 2:
d.onmouseout= e.onmouseout;
d.onmouseover= e.onmouseover;
d.onclick= e.onclick;
d.onmouseup= e.onmouseup;
})();
</script></body></html> | | | | re: 'this', event handlers, and namespaces
Jorge wrote: Quote:
On May 16, 1:27 am, Jeff Bigham <jeffrey.big...@gmail.comwrote: Quote:
>Anyone know what is the accepted standard of what to do in this case?
>[...]
>
<html lang="en"><head>
<title>untitled</title></head><body>
<script>
var c= ": No closure";
(function () {
var d, e, c= ": anon f closure !";;
var y= function (p) { return document.createElement(p) };
var z= function (p) { return document.body.appendChild(p) };
var x= function (p) {
z(y('br'));
(z(y('text'))).innerHTML= p;
};
>
var foo= function (e) {
var c= ": foo closure !";
var me= arguments.callee;
me.doAlert= function() { x(this.src+': onClick'+c) };
var doAlert= function() { x(this.src+': onMouseUp'+c) };
>
//function object method : foo.doAlert()
e.onclick= me.doAlert;
[...]
Sorry, this does not come even close to an approach that could make it to
standard procedure, much less to the standards-compliant approach that the
OP was following already. It is not even Valid markup to begin with: http://validator.w3.org/
PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16 | | | | re: 'this', event handlers, and namespaces Quote: Quote:
Anyone know what is the accepted standard of what to do in this case?
>
There is no accepted standard about it, only common sense guided by the text
of the ECMAScript Specification and by the reality of its implementations.
Thanks. What you suggested worked well.
-Jeff Quote:
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
| | | | re: 'this', event handlers, and namespaces
* Jeff Bigham wrote in comp.lang.javascript : Quote:
>Consider the following simplified code in which Foo is used as a
>'namespace':
>
>var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: function(e) {
this.doAlert();
}
>}
>
>document.addEventListener('keydown', Foo.doAlert, false);
You would have to call the event handler method 'handleEvent' and pass
the object rather than the function to addEventListener, i.e., like so:
var Foo = {
doAlert: function() {
alert('hello');
},
handleEvent: function(e) {
this.doAlert();
}
}
document.addEventListener('keydown', Foo, false);
With your approach `this` should always be bound to e.currentTarget.
--
Björn Höhrmann · mailto:bjoern@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/ |  | Similar JavaScript / Ajax / DHTML bytes | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,510 network members.
|