为什么事件侦听器执行以下代码



我在udemy AJAX课程中构建了这段代码。我很感激您对为什么我的事件监听器在被点击之前执行console.log代码,并且控制台将正确答案记录4次(命名为a(作为ansChecker函数的一部分的解释。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Ajax</title>
<style>
</style>
</head>
<body>
<h1>Trivia api</h1>
<div>Score: <span id="score"></span></div>
<div id="output"></div>
<div id="selAnswers"></div>
<input type="button" id="btn" value="Next Question">
<script>
var btn = document.getElementById('btn').addEventListener('click', getItem);
var answers = {
'correct': 0,
'incorrect': 0
};
function getItem() {
var url = "https://opentdb.com/api.php?amount=1";
var output = document.getElementById('output');
requestAjax(url, function(data) {
var info = data.results[0];
console.log(info);
output.innerHTML = '<div>Category: ' + info.category + '</div>';
output.innerHTML += '<div>Question: ' + info.question + '</div>';
questionBuilder(info.correct_answer, info.incorrect_answers);
});
}
function questionBuilder(corr, incorr) {
/*console.clear();*/
var holder = incorr;

holder.push(corr);
holder.sort();
var selAnswers = document.getElementById('selAnswers');
for (i in holder) {
//                selAnswers.innerHTML ='';
selAnswers.innerHTML += '<input type="button" id="answer" value="' + holder[i] + '">';
document.getElementById('answer').addEventListener('click', ansChecker(corr));
}
}
function ansChecker(a) {
console.log(a);
}
function requestAjax(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
callback(JSON.parse(xhr.responseText));
}
}
xhr.open('GET', url, true);
xhr.send();
}
</script>
</body>
</html>

以下行执行ansChecker函数,而不是将其作为回调传递给事件侦听器:

document.getElementById('answer').addEventListener('click', ansChecker(corr));

参数应该在回调函数中绑定或调用,如下所示:

// Within callback example
document.getElementById('answer').addEventListener('click', () => ansChecker(corr));
// Binded example
document.getElementById('answer').addEventListener('click', ansChecker.bind(this, corr);

一般来说,MDN是一个阅读预期参数的好地方,并且有很好的例子可以帮助你:

AddEventListener:
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

绑定:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind


对于您的第二个问题,由于事件侦听器连接到的目标,它将控制台Counter-Strike4 4次:

document.getElementById('answer');

这将把事件监听器附加到它找到的id为answer的第一个元素上,在这种情况下,它将始终是Counter Strike输入。此外,id对于整个页面DOM应该是唯一的,所以不要重复使用同一个。有不同的方法来针对每个答案的各个元素。一种方法是执行以下操作:

holder.forEach(value => {
let inputEl = document.createElement('input');
inputEl.setAttribute('type', 'button');
inputEl.setAttribute('value', value);
selAnswers.appendChild(inputEl);
inputEl.addEventListener('click', () => ansChecker(corr));
});

最新更新