By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,716 Members | 1,304 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,716 IT Pros & Developers. It's quick & easy.

Binding Javascript Class Method with Element Event

P: n/a
I've been reading through quite a bit regarding this topic but am
finding myself confused.

Here is the scenario:

I have a javascript class defined with methods whereas each has
references to "this." As everyone is aware of, when you attach and
event from an element to a class method and the class method
references "this", the scope of "this" refers not to the class but
rather to the element firing the event.

So, lets consider the following code:

function objclass {
this.parentDiv = document.getElementById("parentdiv");
this.x = 0;
this.y = 0;

this.elementScrolled = elementScrolled;
this.createElement= createElement;
}

function elementScrolled() {
this.x = this.parentDiv.scrollLeft;
this.y = this.parentDiv.scrollTop;
alert(this.x + "x" + this.y);
}

function createElement() {
var element = document.createElement("div");
element.id = "parentdiv";
element.onscroll = this.elementScrolled();
this.parentDiv.appendChild(element);
}

If I run this code, the references to this.x and this.y return
nothing... or "undefined."

How do I solve this problem? I want to be able to access the "this"
reference within my event handler. Any quick fix suggestions?

Thank you!

Jun 27 '08 #1
Share this Question
Share on Google+
4 Replies


P: n/a
* sj************@gmail.com wrote in comp.lang.javascript:
>I have a javascript class defined with methods whereas each has
references to "this." As everyone is aware of, when you attach and
event from an element to a class method and the class method
references "this", the scope of "this" refers not to the class but
rather to the element firing the event.
You can give your "class" a "method" 'handleEvent' inside of which
`this` will be bound to the object you registered, for example,

var T = { handleEvent: function(evt) { ... } };
document.addEventListener('click', T, false);

Other than that you'll have to store a reference to the desired
object in the function you are registering, for example, you could
just use something like function(evt) { obj.meth(evt); }.
--
Björn Höhrmann · mailto:bj****@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/
Jun 27 '08 #2

P: n/a
On Apr 26, 1:44*pm, Bjoern Hoehrmann <bjo...@hoehrmann.dewrote:
* sjkothenbeu...@gmail.com wrote in comp.lang.javascript:
I have a javascript class defined with methods whereas each has
references to "this." *As everyone is aware of, when you attach and
event from an element to a class method and the class method
references "this", the scope of "this" refers not to the class but
rather to the element firing the event.

You can give your "class" a "method" 'handleEvent' inside of which
`this` will be bound to the object you registered, for example,

* var T = { handleEvent: function(evt) { ... } };
* document.addEventListener('click', T, false);

Other than that you'll have to store a reference to the desired
object in the function you are registering, for example, you could
just use something like function(evt) { obj.meth(evt); }.
--
Björn Höhrmann · mailto:bjo...@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/
mmmm... any chance you can show me how by altering my code? I'm still
confused. Also, I'm using IE.

thanks!
Jun 27 '08 #3

P: n/a
sj************@gmail.com wrote:
mmmm... any chance you can show me how by altering my code? I'm still
confused. Also, I'm using IE.

thanks!
An alternative is a function that returns a function that uses apply to
bind this to the called function:

/*
* o = object
* f = function name
*/
function EventObjectBind(o, f)
{
return function(){o[f].apply(o, arguments)}
}
You use it like this:

element.onscroll = EventObjectBind(this, 'elementScrolled');
Jun 27 '08 #4

P: n/a
sj************@gmail.com wrote:
Here is the scenario:

I have a javascript class
There is no such thing so far, the target implementations are
prototype-based object-oriented programming languages.

You have a _constructor_ for an object.
defined with methods whereas each has
references to "this." As everyone is aware of, when you attach and
event from an element to a class method and the class method
references "this", the scope of "this" refers not to the class but
rather to the element firing the event.
So much for "everyone" aware of something that does not even exist.
So, lets consider the following code:

function objclass {
this.parentDiv = document.getElementById("parentdiv");
this.x = 0;
this.y = 0;

this.elementScrolled = elementScrolled;
this.createElement= createElement;
}

function elementScrolled() {
this.x = this.parentDiv.scrollLeft;
this.y = this.parentDiv.scrollTop;
alert(this.x + "x" + this.y);
}

function createElement() {
var element = document.createElement("div");
element.id = "parentdiv";
element.onscroll = this.elementScrolled();
There isn't really a need for this method, your constructor can do all that.

You are assigning the return value of the method here instead of a reference
to it. But even if you omitted the `()', it will not work as desired
because the right-hand side would be just a reference to a Function object
that does not "know" of an owning object.

Therefore, you are looking for

var me = this;
element.onscroll = function() {
me.elementScrolled();
};

Besides, `onscroll' is a proprietary property that should be feature-tested
for before being used.

And for recent implementations it is unnecessary to declare the method globally:

objclass.prototype.elementScrolled = function(...) {
this.x = ...
...
};

Or, if you need a closure over the constructor's execution context:

function objclass(...)
{
...

this.elementScrolled = function(...) {
this.x = ...
...
};

...
}

By convention, your constructor identifier should begin with a capital
letter (here: at least Objclass, or probably something more descriptive);
other identifiers, except those for constants, should not.
this.parentDiv.appendChild(element);
}

If I run this code, the references to this.x and this.y return
nothing... or "undefined."
In fact, with your current code the event listener would never be called
because the premature method call returns `undefined' (as there is no
`return' statement in it that says otherwise) and so `undefined' is assigned
to the `onscroll' property.
How do I solve this problem? I want to be able to access the "this"
reference within my event handler. Any quick fix suggestions?
HTH

PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f8*******************@news.demon.co.uk>
Jun 27 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.