[英]How do I attach eventListeners to dynamically generated radio buttons?
我想为每个单选输入点击附加一个事件侦听器,以便我可以检索该单选输入的值并将其分配为 allQuestions 数组中当前问题对象中的新属性的值。
我不确定为什么我很难让choice.addEventListener
工作。
我的HTML:
<div id="quiz"></div>
<button id="button">Next</button>
我的脚本:
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);
您正在尝试同时使用标记和 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
所做的)。
现在,话虽如此,您不需要每个单选按钮上的处理程序。 相反,您可以通过在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
开始循环并转到其parentNode
以找到您感兴趣的元素(假设您对div
感兴趣,但点击是在span
上在里面); 但是当然, input
元素里面不能有任何元素,所以这里很简单。
您可能想知道为什么要检查标签名称。 如果将单选按钮与label
元素相关联(这通常是一种好的做法),无论是通过将input
放在label
内还是在标签上使用for
属性,当您单击label
时,您将看到两次点击:一次在label
上本身,第二个在标签相关的input
上。 我们只对实际单选按钮上的那个感兴趣。
这是上面委托的一个简单示例:
var quiz = document.getElementById("quiz"); quiz.addEventListener("click", function(e) { if (e.target.tagName.toUpperCase() === "INPUT") { var value = e.target.value; // The value of the clicked radio button console.log("The value of that radio button is " + value); } }); for (var n = 0; n < 5; ++n) { var div = document.createElement("div"); div.innerHTML = '<label><input type="radio" value="' + n + '" name="answer"> Radio ' + n + '</label>'; quiz.appendChild(div); }
<div id="quiz"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.