2017-06-21 152 views
1

我正在创建一个测验应用程序,并决定从.onclick()切换到.addEventListener()。为了让这个工作,我不得不添加事件处理程序。将“this”添加到事件侦听器?

我得到了听众的工作是通过添加以下代码到测验对象的构造,唯一的方法..

document.getElementById('guess0').addEventListener('click', this); 
document.getElementById('guess1').addEventListener('click', this); 

这工作,但我不知道为什么。 “this”到底是做什么的?代码

整个页面以供参考:

function Quiz(questions) { 
    this.questions = questions; 
    this.score = 0; 
    this.currentQuestionIndex = -1; 

    document.getElementById('guess0').addEventListener('click', this); 
    document.getElementById('guess1').addEventListener('click', this); 

    this.displayNext(); 
} 

Quiz.prototype.displayNext = function(){ 
    this.currentQuestionIndex++; 

    if(this.hasEnded()){ 
    this.displayScore(); 
    this.displayProgress(); 
    }else{ 
    this.displayCurrentQuestion(); 
    this.displayCurrentChoices(); 
    this.displayProgress(); 
    } 
}; 

Quiz.prototype.hasEnded = function() { 
return this.currentQuestionIndex >= this.questions.length; 
}; 

Quiz.prototype.displayScore = function() { 
    let gameOverHtml = "<h1>Game is over!</h1>"; 
    gameOverHtml += "<h2>Your score was: " + this.score + "!</h2>"; 

    let quizDiv = document.getElementById('quizDiv'); 
    quizDiv.innerHTML = gameOverHtml; 
}; 

Quiz.prototype.getCurrentQuestion = function() { 
    return this.questions[this.currentQuestionIndex]; 
}; 

Quiz.prototype.displayCurrentQuestion = function() { 
    let currentQuestion = document.getElementById('question'); 
    currentQuestion.textContent = this.questions[this.currentQuestionIndex].text; 
}; 

Quiz.prototype.displayCurrentChoices = function() { 
    let choices = this.getCurrentQuestion().choices; 

    for (let i = 0; i < choices.length; i++) { 
    let choiceHTML = document.getElementById('choice' + i); 
    choiceHTML.innerHTML = choices[i]; 
    } 
}; 

Quiz.prototype.handleEvent = function(event){ 
    if(event.type === 'click'){ 
    this.handleClick(event); 
    } 
}; 

Quiz.prototype.handleClick = function(event){ 
    event.preventDefault(); 
    let choices = this.getCurrentQuestion().choices; 

    if(event.target.id === "guess0"){ 
    this.guess(choices[0]); 
    } else if(event.target.id === "guess1"){ 
    this.guess(choices[1]); 
    } 
    this.displayNext(); 
}; 

Quiz.prototype.displayProgress = function() { 
    let footer = document.getElementById('quizFooter'); 
    if (this.hasEnded()) { 
    footer.innerHTML = "You have completed the quiz!"; 
    } else { 
    footer.innerHTML = "Question " + (this.currentQuestionIndex + 1) + " of " + this.questions.length; 
    } 
}; 

Quiz.prototype.guess = function(choice) { 
    if (this.getCurrentQuestion().checkAnswer(choice)) { 
    this.score++; 
    } 
}; 
+2

看起来不正确 - 这是什么'这个'你添加这个奇怪的代码 –

+0

我添加了整个页面的代码供参考。 –

+0

在JavaScript中,这不是一个单纯的功能。您创建了函数构造函数。当你使用这个函数构造函数(Quiz类型的对象)创建一个对象时,这个'this'引用该对象。 – Karpak

回答

3

您正在Quiz一个“类”(我们通常想到的类,就算JS并没有真正让他们)。当您执行quiz = new Quiz(questions)时,在Quiz构造函数中,this引用新创建的Quiz对象。 addEventListener可以接受listener参数的两个不同值中的一个:

这必须是实现EventListener接口的对象,或JavaScript函数。

您的Quiz通过实现handleEvent函数来实现必要的接口。因此,当您将新创建的测验(如this)传递至addEventListener时,您会在事件发生时调用quiz.handleEvent

+0

它如何区分handleEvent和handleClick方法?因为他们都收到一个事件作为参数。 –

+0

它没有。它只需要'handleEvent',如[这里](https://developer.mozilla.org/en/docs/Web/API/EventListener)。您的'handleClick'明确地从'handleEvent'中调用,但它可以被称为'eatGrassThenMoo',并接受更多的叶菜参数,适用于所有浏览器。 – Amadan

+0

我明白你在说什么了!谢谢 –

相关问题