为什么这个jQuery .change事件在.click事件之后停止工作

时间:2015-05-22 17:55:48

标签: javascript jquery

我有一个脚本显示数组中的问题,并使用两个按钮上的.click事件从一个问题切换到下一个问题:上一个和下一个。当我加载页面时$(":radio").change选择器工作正常,但当我点击上一个或下一个时它停止工作。

我尝试将$("#previous)更改为console.log以查看.click是否是罪魁祸首并且似乎正在运行。我认为我的显示功能有问题,但我似乎无法弄清楚原因。

这是jsFiddle。以下是GitHub

上的项目

问题数组

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);
});

4 个答案:

答案 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,并使用它来获取对元素的引用,情况会发生变化吗?