我想为每个无线电输入点击附加一个事件监听器,以便我可以检索该无线电输入的值并将其指定为allQuestions数组中当前问题对象中新属性的值。
我不确定为什么我在choice.addEventListener
工作时遇到困难。
我的HTML:
<div id="quiz"></div>
<button id="button">Next</button>
我的JavaScript:
var allQuestions = [{question: "What is the capital of the Czech Republic?",
choices: ["Skopje", "Budapest", "Prague", "Bucharest"],
correctAnswer: 2},
{question: "When was the Declaration of Independence signed?",
choices: ["1492", "1776", "1812", "1791"],
correctAnswer: 1}];
var quiz = document.getElementById("quiz");
var index = -1;
var next = function() {
index += 1;
quiz.innerHTML = "";
for (var i = 0; i < allQuestions[index]['choices'].length; i++) {
var choice = document.createElement('input');
choice.type = 'radio';
choice.name = 'choices';
choice.value = i;
choice.addEventListener('click', function() {
alert('hi');
});
quiz.appendChild(choice);
quiz.innerHTML += allQuestions[index]['choices'][i] + '<br>';
}
};
var button = document.getElementById('button');
button.addEventListener('click', next);
答案 0 :(得分:4)
您正在尝试同时使用标记和DOM元素。这是主要问题:
quiz.appendChild(choice);
quiz.innerHTML += allQuestions[index]['choices'][i] + '<br>';
第一行将带有附加事件处理程序的DOM元素附加到quiz
元素。第二行将quiz
的内容转换为HTML字符串,将一些其他文本(标记)附加到该字符串,然后解析该HTML并替换 quiz
的内容解析后的结果。这消除了HTML中未表示的任何内容,包括动态添加的事件处理程序。
解决方案不是做innerHTML += ...
,这几乎总是一个坏主意。在这种特殊情况下,您可以这样做:
quiz.appendChild(choice);
quiz.appendChild(document.createTextNode(allQuestions[index]['choices'][i]));
quiz.appendChild(document.createElement('br'));
...其中还有一个优点,即HTML中特殊的任何字符(如<
)都是按字面意思处理的(因为那是createTextNode
所做的事情。)
现在,说完了,你不需要每个单选按钮上的处理程序。相反,您可以使用<{1}}元素上的处理程序使用事件委派,然后在处理程序中使用quiz
来了解单击了哪个单选按钮:
e.target
这样,您就不必担心动态添加处理程序;在已知quiz.addEventListener("click", function(e) {
if (e.target.tagName.toUpperCase() === "INPUT") {
var value = e.target.value; // The value of the clicked radio button
}
});
元素存在之后,只需执行一次即可,您可以随意更新其内容,而无需担心将处理程序附加到其中的单选按钮。
要进行一般的事件委托,您通常必须从quiz
开始循环并转到e.target
才能找到您感兴趣的元素(比如说&#39;对parentNode
感兴趣,但点击位于div
内;但是,span
元素当然不能包含任何元素,所以这里很简单。
您可能想知道检查标签名称的原因。如果您将单选按钮与input
元素相关联(通常是一种良好做法),可以将label
置于 input
内或使用{{1 label
上的{}}属性,当您点击for
时,您会看到两次点击:标签本身上有一个,label
上有第二个点击1}}标签与之相关。我们只对实际单选按钮上的那个感兴趣。
以上是代表团的一个简单示例:
label
&#13;
input
&#13;