为什么事件监听器我只添加了由Id而不是类获得的元素的作品?

时间:2018-02-17 18:34:56

标签: javascript html button addeventlistener

我正在尝试制作一个非常简单的java脚本测验来尝试学习该语言。

var result = document.getElementById("result");

var rightAnswer = document.getElementById("correct").addEventListener("click",correctAnswer);

function correctAnswer(){
 result.innerText="Correct";
};

var wrongAnswer = document.getElementsByClassName("wrong").addEventListener("click",wrongAnswer);

function wrongAnswer(){
 result.innerText="Wrong";
};

当我运行它并测试正确的答案工作正常但错误的答案没有响应。当我在控制台中查看时,它表示“document.getElementsByClassName(...)。addEventListener不是一个函数”,这让我感到困惑,因为除了“getElementsByClassName”之外,我看到的格式与其他行完全一样。我是否可以不将同一个事件监听器添加到同一个类的多个按钮中? HTML

<!DOCTYPE html>
<html>

<head>
<title>Quiz</title>

</head>

<body>
<p>Who was the first president of the United States?</p>

<button class='button wrong' type='button'>Thomas Jefferson</button>

<button class='button' id='correct' type='button'>George Washington</button>

<button class='button wrong' type='button'>James Madison</button>

<button class='button wrong' type='button'>John F Kennedy</button>

<p id='result'></p>

<script src='quiz.js'></script>

</body>

</html>

2 个答案:

答案 0 :(得分:1)

错误控制台中的错误是因为您无法将addEventListener()链接到getElementsByTagName()

getElementsByTagName()返回节点 set ,而addEventListener()是HTML 节点对象的方法,而非节点集对象。

换句话说,它在单个节点上运行。这意味着我们要么迭代节点集并将事件绑定到找到的每个节点,要么使用事件委托。

迭代方法

var wrong = document.querySelectorAll(".wrong");
wrong.forEach(function(el) {
    el.addEventListener("click",wrongAnswer, false);
});

委派方法

使用事件委派,您不会绑定到每个节点,而是绑定到公共父节点或祖先节点。然后,您询问哪个节点触发了该事件。

我们可以依靠这个因为事件&#34; bubble&#34 ;;它们不仅触发了它们所绑定的元素,而且触发了从最里面向外的元素的子节点或后代节点。

换句话说,触发元素(evt.target)和上下文元素(this)可能不是同一个。

让我们假设您的所有.wrong元素都位于一个公共容器中,ID为#wrong

然后我们可以这样做:

document.querySelector('#wrong').addEventListener('click', function(evt) {
    var trigger_el = evt.target;
    if (!evt.target.matches('.wrong') return; //do nothing - was some other element
    wrongAnswer.call(trigger_el); //call wrongAnswer in the context of the trigger element
}, false);

答案 1 :(得分:1)

你需要循环遍历document.getElementsByClassName(&#34;错误&#34;)的结果才能添加事件,因为getElement s ByClassName将始终返回多个元素。你可以这么做:

var wrongAnswer = document.getElementsByClassName("wrong");
for(n = 0; n < wrongAnswer.length; n++){
  wrongAnswer[n].addEventListener("click",wrongAnswer);
}