我有一个脚本显示数组中的问题,并使用两个按钮上的.click
事件从一个问题切换到下一个问题:上一个和下一个。当我加载页面时$(":radio").change
选择器工作正常,但当我点击上一个或下一个时它停止工作。
我尝试将$("#previous)
更改为console.log以查看.click
是否是罪魁祸首并且似乎正在运行。我认为我的显示功能有问题,但我似乎无法弄清楚原因。
问题数组
var quizQuestions =
[{
question: "1. Who is Prime Minister of the United Kingdom?",
choices: ["David Cameron", "Gordon Brown", "Winston Churchill", "Tony Blair"],
correctAnswer:0
},
{
question: "2. Who is Prime Minister of the United Kingdom?",
choices: ["David Cameron", "Gordon Brown", "Winston Churchill", "Tony Blair"],
correctAnswer:2
},
{
question: "3. Who is Prime Minister of the United Kingdom?",
choices: ["David Cameron", "Gordon Brown", "Winston Churchill", "Tony Blair"],
correctAnswer:1
}];
JavaScript代码(jQuery)
$(document).ready(function(){
var all = quizQuestions,
q = $("#question"),
c = $("#choices"),
ans = [],
current = 0;
display(current);
function display (id) {
var question = all[id].question;
var choices = all[id].choices;
q.html(question);
c.html(function(){
var output = "<form>";
for (var i = 0; i < choices.length; i++) {
output += "<input type='radio' name='question" +id
+ "' value='" + choices[i] + "'> "
+ choices[i] + "<br>";
};
output += "</form>"
// console.log(output);
return output;
});
};
function changeDisplay (dir) {
if (dir == 'next' && current < all.length-1) current++;
if (dir == 'prev' && current > 0) current--;
display(current);
}
function answerQ (q, a) {
ans[q] = a;
console.log(ans);
}
$(":radio").change(function(){
answerQ( $(this)[0].name, $(this).val() );
});
$("#previous").click(function (){ changeDisplay('prev'); });
$("#next").click(function (){ changeDisplay('next'); });
// console.log("all.length: " + all.length + " | ans: " + ans + " | current: " + current);
});
答案 0 :(得分:5)
这很可能是因为事件未被委派。加载页面时,您绑定单击事件。但是当操作dom(删除元素)时,事件将被删除。你必须使用delegate。
像这样:
$('.container').on('change', ':radio', function(){
answerQ( $(this)[0].name, $(this).val() );
});
修改:我建议您保存或隐藏答案,而不是覆盖答案。这样可以更容易地实现上一个功能。
答案 1 :(得分:3)
当您转到下一组问题时,您会在每个单选按钮上替换页面上的HTML。但是,您永远不会将点击处理程序分配给新的单选按钮。您在加载页面时最初对所有单选按钮执行此操作,但在更改显示后,您不会将单击处理程序重新应用于单选按钮。
在你的document.ready处理程序中,你接近底部:
$(":radio").change(function(){
answerQ( $(this)[0].name, $(this).val() );
});
但是在显示功能中(当你选择上一个或下一个时调用)你有这个:
c.html(function(){
var output = "<form>";
for (var i = 0; i < choices.length; i++) {
output += "<input type='radio' name='question" +id
+ "' value='" + choices[i] + "'> "
+ choices[i] + "<br>";
};
output += "</form>"
// console.log(output);
return output;
});
其中没有为任何新输入选项添加点击处理程序。
答案 2 :(得分:2)
这就是问题,当你直接添加像&#34; .click()&#34;或者&#34; .change()&#34;等等,对于一个元素,你只是专门为该对象设置监听器。要创建一个适用于当前页面上所有元素的侦听器,以及通过动态方式创建的任何未来元素(ajax,在页面加载完成后通过javascript添加新元素),您应该设置document
级别&#34;上&#34;功能:
更改此处的内容:
$(":radio").change(function(){
answerQ( $(this)[0].name, $(this).val() );
});
到此:
$(document).on("change", ":radio", function(){
answerQ($(this).name, $(this).val());
});
(我不认为$(this)上的[0]意味着什么,因为那时它只适用于 改变的元素。)
希望有所帮助!
以下是关于此主题的更多阅读链接:http://api.jquery.com/on/
答案 3 :(得分:0)
我会将显示功能移出$(document).ready()事件的回调方法。恕我直言,它属于全球空间,因为它被全球空间中的其他功能调用。它比依赖Closure来保持对隐藏在事件处理程序中的对象的引用更简洁。
编辑:我想问题就是使用它,而不是单步执行代码。如果在处理程序.change()中使用事件对象中的pass,并使用它来获取对元素的引用,情况会发生变化吗?