我正在使用jQuery .prototype
构建一个jQuery / javascript Web应用程序。
在以下代码中,我想更新为原型全局值this.score
,我必须bind(this)
才能使其工作。
没有绑定this
我可以使用btnElement
到达$(this)
内的范围,但是在绑定后这不再起作用了。是否有像'this'这样的解决方法? ;)
showQuestion: function(question) {
this.quiz.show();
var btnElement = this.quiz.find('div');
btnElement.on('click', function() {
var btn = $(this).find('span');
if (btn.hasClass('correct')) {
btn.addClass('good');
this.score += 1;
} else {
$('span.correct').addClass('good');
btn.addClass('wrong');
}
}.bind(this));
}
答案 0 :(得分:4)
您已绑定了自己的事件回调,因此其中的this
是指其外部this
引用的内容。这意味着您无法在jQuery事件处理程序(与事件相关的DOM元素)中使用通常含义btnElement
。
处理这个问题的三种方法:
请使用showQuestion: function(question) {
this.quiz.show();
var btnElement = this.quiz.find('div');
btnElement.on('click', function() {
var btn = btnElement.find('span'); // <====
if (btn.hasClass('correct')) {
btn.addClass('good');
this.score += 1;
} else {
$('span.correct').addClass('good');
btn.addClass('wrong');
}
}.bind(this));
}
,因为您可以使用它:
this
使用e.currentTarget
,如果处理程序未绑定,则showQuestion: function(question) {
this.quiz.show();
var btnElement = this.quiz.find('div');
btnElement.on('click', function(e) { // <====
var btn = $(e.currentTarget).find('span'); // <====
if (btn.hasClass('correct')) {
btn.addClass('good');
this.score += 1;
} else {
$('span.correct').addClass('good');
btn.addClass('wrong');
}
}.bind(this));
}
会是同样的事情(在这种情况下,您也可以使用e.delegateTarget
,因为它不是委托的处理程序,所以它是相同的值):
e.target
我没有推荐e.target
,因为它不是相当同样的事情:this
是事件发生的元素; e.target
是您将事件挂钩的元素。因此,div
可能是您的测验this
的后代元素。
不要绑定事件处理程序,而是在事件处理程序关闭的变量中存储对showQuestion: function(question) {
var self = this; // <====
self.quiz.show();
var btnElement = this.quiz.find('div');
btnElement.on('click', function() {
var btn = $(this).find('span');
if (btn.hasClass('correct')) {
btn.addClass('good');
self.score += 1; // <====
} else {
$('span.correct').addClass('good');
btn.addClass('wrong');
}
}); // <====
}
的引用:
{{1}}
答案 1 :(得分:2)
一种方法是 NOT 绑定并在点击处理程序之外使用对this
的引用
showQuestion: function(question) {
this.quiz.show();
var btnElement = this.quiz.find('div');
var self = this; // create a reference to this
btnElement.on('click', function() {
var btn = $(this).find('span'); // you will still be able to find the span which is inside the btnElement
if (btn.hasClass('correct')) {
btn.addClass('good');
self.score += 1; // you will still be able to refer this which is reference as self outside
} else {
$('span.correct').addClass('good');
btn.addClass('wrong');
}
});
}
其他方式是将参数发送到bind
(除了其他答案中的所有其他选项)
showQuestion: function(question) {
this.quiz.show();
var btnElement = this.quiz.find('div');
btnElement.on('click', function(event, btnElement) { //
var btn = btnElement.find('span');
if (btn.hasClass('correct')) {
btn.addClass('good');
this.score += 1;
} else {
$('span.correct').addClass('good');
btn.addClass('wrong');
}
}.bind(this, btnElement));
}
这也只是将按钮引用发送到自己的单击处理程序有点奇怪。