How to Run Object's Function on Click of a Link?

V

vunet

How can I initialize a function within the object on click of this
objects link element appended to body? Simply, see onclick which DOES
initialize my doSomething function but does NOT see myArray:

fucntion Test(){
this.myArray = new Array();
this.doSomething = function(){
this.myArray.push("blah")
}
var aLink = document.createElement("a")
aLink.innerHTML = "Do something";
aLink.onclick = this.doSomething;
document.body.appendChuild(aLink);
}
new Test();

Error: myArray has no properties
 
T

T.J. Crowder

How can I initialize a function within the object on click of this
objects link element appended to body? Simply, see onclick which DOES
initialize my doSomething function but does NOT see myArray:

fucntion Test(){
this.myArray = new Array();
this.doSomething = function(){
this.myArray.push("blah")
}
var aLink = document.createElement("a")
aLink.innerHTML = "Do something";
aLink.onclick = this.doSomething;
document.body.appendChuild(aLink);}

new Test();

Error: myArray has no properties

Hi,

The reason you're getting that error is that you're passing just a
function reference to the click handler; there's nothing about the
instance included. 'this' in the context of the click handler's code
is not the 'this' of your Test function (it's probably the window
object, since it looks like you're using DOM0 event handling rather
than addEventListener/attachEvent, although perhaps on some browsers
it's the link element [I don't know, haven't used DOM0 event handling
on recent versions of browsers]). More about how to remember 'this'
in your event handler and why you need to here (disclosure - it's my
blog):
http://blog.niftysnippets.org/2008/04/you-must-remember-this.html
Simply, see onclick which DOES
initialize my doSomething function but does NOT see myArray:

That's a different question from the reason for your error. The
answer is that you can't do that, not as the code is currently
formulated, because you've set up myArray as a property on the object,
and all object properties are public. If it's really important to you
to have myArray actually be private, there are patterns for doing it
with closures:
http://www.crockford.com/javascript/private.html

Hope this helps,
 
V

vunet

How can I initialize a function within the object on click of this
objects link element appended to body? Simply, see onclick which DOES
initialize my doSomething function but does NOT see myArray:
fucntion Test(){
this.myArray = new Array();
this.doSomething = function(){
this.myArray.push("blah")
}
var aLink = document.createElement("a")
aLink.innerHTML = "Do something";
aLink.onclick = this.doSomething;
document.body.appendChuild(aLink);}
new Test();
Error: myArray has no properties

Hi,

The reason you're getting that error is that you're passing just a
function reference to the click handler; there's nothing about the
instance included. 'this' in the context of the click handler's code
is not the 'this' of your Test function (it's probably the window
object, since it looks like you're using DOM0 event handling rather
than addEventListener/attachEvent, although perhaps on some browsers
it's the link element [I don't know, haven't used DOM0 event handling
on recent versions of browsers]). More about how to remember 'this'
in your event handler and why you need to here (disclosure - it's my
blog):http://blog.niftysnippets.org/2008/04/you-must-remember-this.html
Simply, see onclick which DOES
initialize my doSomething function but does NOT see myArray:

That's a different question from the reason for your error. The
answer is that you can't do that, not as the code is currently
formulated, because you've set up myArray as a property on the object,
and all object properties are public. If it's really important to you
to have myArray actually be private, there are patterns for doing it
with closures:http://www.crockford.com/javascript/private.html

Hope this helps,

Thank you. I will read more about "this". But how would I run
doSomething with onclick event which I build inside of the object and
append to body? How would I implement something like this?
 
T

T.J. Crowder

How can I initialize a function within the object on click of this
objects link element appended to body? Simply, see onclick which DOES
initialize my doSomething function but does NOT see myArray:
fucntion Test(){
this.myArray = new Array();
this.doSomething = function(){
this.myArray.push("blah")
}
var aLink = document.createElement("a")
aLink.innerHTML = "Do something";
aLink.onclick = this.doSomething;
document.body.appendChuild(aLink);}
new Test();
Error: myArray has no properties

The reason you're getting that error is that you're passing just a
function reference to the click handler; there's nothing about the
instance included. 'this' in the context of the click handler's code
is not the 'this' of your Test function (it's probably the window
object, since it looks like you're using DOM0 event handling rather
than addEventListener/attachEvent, although perhaps on some browsers
it's the link element [I don't know, haven't used DOM0 event handling
on recent versions of browsers]). More about how to remember 'this'
in your event handler and why you need to here (disclosure - it's my
blog):http://blog.niftysnippets.org/2008/04/you-must-remember-this.html
Simply, see onclick which DOES
initialize my doSomething function but does NOT see myArray:
That's a different question from the reason for your error. The
answer is that you can't do that, not as the code is currently
formulated, because you've set up myArray as a property on the object,
and all object properties are public. If it's really important to you
to have myArray actually be private, there are patterns for doing it
with closures:http://www.crockford.com/javascript/private.html
Hope this helps,

Thank you. I will read more about "this". But how would I run
doSomething with onclick event which I build inside of the object and
append to body? How would I implement something like this?

See the link; there are two solutions given there.
 
V

vunet

See the link; there are two solutions given there.

Is it that I have to add

self=this;
//aLink.onclick = doSomething //remove
aLink.addEventListener("click", self.doSomething, true);

Still does not work. I am a bit puzzled in this.
 
T

T.J. Crowder

Hi,
aLink.addEventListener("click", self.doSomething, true);

Still does not work. I am a bit puzzled in this.

That doesn't work for the same reason that using this.doSomething
doesn't work.

The blog post I linked to has working examples of two ways to solve
this problem, with code. If you give it a thorough read and read the
explanations of the syntax, you should be good to go.
 
V

vunet

Hi,



That doesn't work for the same reason that using this.doSomething
doesn't work.

The blog post I linked to has working examples of two ways to solve
this problem, with code. If you give it a thorough read and read the
explanations of the syntax, you should be good to go.

Ahhhhhhhh...
aLink.addEventListener("click", function(){self.doSomething(vals)},
true);
thank you.
 
T

T.J. Crowder

Ahhhhhhhh...
aLink.addEventListener("click", function(){self.doSomething(vals)},
true);
thank you.

No worries. Yes, that's one of the ways to do it. Not my personal
favorite, but it does work.
 
D

dhtml

That's a different question from the reason for your error.  The
answer is that you can't do that, not as the code is currently
formulated, because you've set up myArray as a property on the object,
and all object properties are public.  If it's really important to you
to have myArray actually be private, there are patterns for doing it
with closures:http://www.crockford.com/javascript/private.html

Another way to get there is to use a callback handler that can find
the object instance:-

Widget.clickHandler = function(e) {
e = e||event;

var target = e.target||e.srcElement;
// filter out unwanted nodes....

var widget = Widget.instances[ target.id ];

if(widget) {
// found.
}
};

This assumes that Widget has an - instances - property that has
instances keyed by an associated node's ID.

function Widget(id){ };

Widget.getById = function(id) {
if(!this.hasOwnProperty("instances")) this.instances = {};
return this.instances.hasOwnProperty(id) && this.instances[id]
|| (this.instances[id] = new this(id));
};


There's a lot more that can be done with this approach, including
instantiating a widget on a bubbled event, on demand, for example.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,266
Messages
2,571,081
Members
48,772
Latest member
Backspace Studios

Latest Threads

Top