问题
Possible Duplicate:
How do I pass the this context into an event handler?
I am doing a Javascript related assignment and am required to make a calendar which is associated with a particular input.
The calendar is displayed constantly and does not hide, etc.
There can be multiple calendars pointing to different text fields.
Now, each calendar is created by a Javascript object, i.e.
var cal1=new Calendar("inputfield_id");
Now the calendar object has certain variables that I want to access when the calendar is clicked on.
So basically, my question is, is there a way to get a particular object for an onclick event, i.e. somehow getting the "this" variable when you are in an object.
Here's a small portion of the code to explain what I am trying to do:
function calendar(id){
this.date=new Date();
this.id=id;
this.next_year=function(){
this.date.setFullYear(this.date.getFullYear()+1);
alert(this.date); // basically I want to get object context here to change date
}
var temp_but=document.createElement("button").onclick=this.next_year;
document.getElementById(id+"_div").appendChild(temp_but);
document.getElementById(id+"_div").lastChild.onclick=this.next_year;
}
basically, in this.nextyear
function, I want to get object context to get date and change calendar accordingly.
回答1:
I think this is what you're looking to do...
function calendar(id){
this.date=new Date();
this.id=id;
var context = this;
this.next_year=function(){
context.date.setFullYear(context.date.getFullYear()+1);
alert(context.date);//basically i want to get object context here to change date
}
var temp_but=document.createElement("button").onclick=this.next_year;
document.getElementById(id+"_div").appendChild(temp_but);
document.getElementById(id+"_div").lastChild.onclick=this.next_year;
}
Essentially, we're using a closure to preserve a reference to this
called context
. this.next_year
now has a reference to the calendar object via context
.
EDIT: a little JS lesson in response to the comment OP posted.
When you call a function as a constructor (i.e. new
calendar("example")
), a new empty object is created and the function is executed in the context of the new empty object.
note: It's not really just an empty object. It's an empty object with certain internal pointers behind the scenes for things like prototypal inheritance.
Anywho! Throughout a function, any reference to this refers to the current context. And, because when you use a function as a constructor, it calls the function in the context of a newly created object, you can set properties of the object using this.someProperty
.
When you execute the statement var cal1=new calendar("inputfield_id");
, a new object is created, and your function calendar
gets executed in the context of said object. So, this.date=new Date();
and this.id=id
are setting the date
and id
properties of your new calendar object.
I'm assuming you aren't actually having trouble understanding what happens here: this.id=id;
but rather why the this
keyword wasn't working in this.next_year
.
Let's start off with a scenario where it would have works. If you were to call cal1.next_year();
, you'd be calling next_year()
in the context of cal1
, so this.date.setFullYear(this.date.getFullYear()+1);
would increment cal1
's date property by 1 year as expected.
It wasn't working at the click event handler because when you set the event handler, you're kind of saying "when the 'click' event is fired, execute this function" as opposed to "when the 'click' event is fired, execute this statement".
the function that's actually executing being:
function(){
this.date.setFullYear(this.date.getFullYear()+1);
alert(this.date);
}
and the statement you were expecting to execute being:
this.next_year(); //where this refers to the calendar object.
When this code is executing,
elem.onclick = this.next_year;
it's the same as saying,
elem.onclick = function(){
this.date.setFullYear(this.date.getFullYear()+1);
alert(this.date);
}
So, if this doesn't make the issue clear enough, let me go a little further and explain what actually happens when an element, elem
, is clicked after a click handler was set using elem.onclick=this.next_year;
. I like to think of it as though the browser is calling elem.onclick([Event event]);
. Essentially, the function you set using elem.onclick=
is executed in the context of elem
and an Event
object is passed in as the first and only argument.
To be blatantly clear and drive the point home, the this
keyword in your function points to the element that was clicked when it's invoked by the browser as an event handler.
function(){
this.date.setFullYear(this.date.getFullYear()+1);
alert(this.date);
}
I apologize for over-explaining and being repetitive/redundant. I try to keep my answers short because I'm generally bad at explaining things :P
PS - don't forget to accept!
来源:https://stackoverflow.com/questions/12879809/javascript-onclick-event-call-object