2017-06-21 138 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

我明白你在說什麼了!謝謝 –