jQuery原型使用$(this)和this

时间:2015-05-24 12:11:33

标签: jquery oop prototype this bind

我正在使用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));
}

2 个答案:

答案 0 :(得分:4)

您已绑定了自己的事件回调,因此其中的this是指其外部this引用的内容。这意味着您无法在jQuery事件处理程序(与事件相关的DOM元素)中使用通常含义btnElement

处理这个问题的三种方法:

  1. 请使用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
  2. 使用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后代元素。

  3. 不要绑定事件处理程序,而是在事件处理程序关闭的变量中存储对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));
}

这也只是将按钮引用发送到自己的单击处理程序有点奇怪。