admin管理员组文章数量:1386798
I have a script that displays questions from an array and switches from one question to the next using the .click
event on two buttons: previous and next. When I load the page the $(":radio").change
selector works fine, but when I click on previous or next it stops working.
I tried changing the $("#previous)
to a console.log to see if .click
was the culprit and it seems to be working. I assume there is something wrong with my display function but I can't seem to figure out why.
Here is the jsFiddle. And here is the project on GitHub
Questions Array
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 Code (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);
});
I have a script that displays questions from an array and switches from one question to the next using the .click
event on two buttons: previous and next. When I load the page the $(":radio").change
selector works fine, but when I click on previous or next it stops working.
I tried changing the $("#previous)
to a console.log to see if .click
was the culprit and it seems to be working. I assume there is something wrong with my display function but I can't seem to figure out why.
Here is the jsFiddle. And here is the project on GitHub
Questions Array
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 Code (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);
});
Share
Improve this question
edited Jun 2, 2015 at 7:50
Peter Rasmussen
17k8 gold badges50 silver badges64 bronze badges
asked May 22, 2015 at 17:55
jeanpier_rejeanpier_re
8351 gold badge6 silver badges23 bronze badges
1
-
There is a
console.log
that I couldn't display on fiddle. It's supposed to display thename
andvalue
of the question/answer being selected. – jeanpier_re Commented May 22, 2015 at 18:04
4 Answers
Reset to default 5This is most likely because the event is not delegated. When the page is loaded you bind the click events. But as the dom is manipulated (elements removed) the events are deleted. You would have to use a delegate for this.
Like this:
$('.container').on('change', ':radio', function(){
answerQ( $(this)[0].name, $(this).val() );
});
Edit: I would suggest that you save or hide the answers instead of overwriting them. That would make it easier to implement the previous function.
It looks like when you move to the next set of questions you replace the HTML on the page for each radio button. However you never assign click handlers to the new radio buttons. You do this initially to all radio buttons when the page is loaded, but after you change the display you don't reapply the click handler to the radio buttons.
In your document.ready handler you have this near the bottom:
$(":radio").change(function(){
answerQ( $(this)[0].name, $(this).val() );
});
But in the display function (called when you choose previous or next) you have this:
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;
});
Which doesn't add a click handler to any of the new input options.
Here's the problem, when you directly add listeners like ".click()" or ".change()", etc, to an element, you're only setting the listener for that object specifically. To create a listener that applies to all elements currently on the page, and also any future elements created through dynamic means (ajax, new elements added via javascript after page load pletes) you should set a document
level "on" function:
Change what you have here:
$(":radio").change(function(){
answerQ( $(this)[0].name, $(this).val() );
});
to this:
$(document).on("change", ":radio", function(){
answerQ($(this).name, $(this).val());
});
(I don't think the [0] on $(this) means anything, because at that moment it would only apply to the element that was just changed anyway).
Hope that helps!
Here's a link for futher reading on the subject: http://api.jquery./on/
I would move the display function out of the callback method for the $(document).ready() event. IMHO, it belongs in the global space because it's being invoked by other functions in the global space. It's just cleaner than relying on a Closure to keep a reference to an object hidden in an event handler.
EDIT: I imagine the problem is the use of this, without stepping through the code. Would things change if you use pass in the event object in your handler .change(), and use that to get a reference to the element?
本文标签: javascriptWhy does this jQuery change event stop working after click eventStack Overflow
版权声明:本文标题:javascript - Why does this jQuery .change event stop working after .click event - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744563139a2612887.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论