【问题标题】:jQuery Ajax call on click only works once点击时的jQuery Ajax调用只能工作一次
【发布时间】:2013-06-24 07:45:03
【问题描述】:

我正在为客户网站构建一个测验,我从 Ajax 调用中获取问题,然后用新问题替换 HTML 内容,问题是我的 Ajax 调用只工作一次,然后如果我失败了再试一次。当我用html() 一次性替换所有内容时,它会失败,但是如果我将它分解为多个部分并为每个部分替换 do html() 它没有问题,但是当我一次完成所有操作时,如果在第一个之后失败有时间,如果有人可以查看我的代码并告诉我为什么会这样,将不胜感激,提前致谢!

HTML

<section class="widget twelve quiz">
    <div class="content">
        <div class="widget six sign">
            <img src="http://www.mysite.com/images/questions/question-1.jpg" alt="">
        </div>
        <div class="widget six question">
            <header>
                <button class="align-right button" data-object='{"qui_id":"0","action":"1","que_id":"1"}'>Skip</button>
            </header>
            <h2>Q: Lorem Ipsum?</h2>
        </div>
        <div class="widget twelve answers">
            <ul>
                <li><button data-object='{"ans_id":"1"}'>A: Lorem 1.</button></li>
                <li><button data-object='{"ans_id":"2"}'>B: Lorem 2.</button></li>
                <li><button data-object='{"ans_id":"3"}'>C: Lorem 3</button></li>
                <li><button data-object='{"ans_id":"4"}'>D: Lorem 4.</button></li>
            </ul>
        </div>
        <div class="widget six navigation">
            <button class="align-right button" data-object='{"qui_id":"0","action":"0","que_id":"1"}'>Next</button>
        </div>
    </div>
</section>

Ajax 调用只工作一次

$('.question,.navigation').on('click', '.button', function() {

    $.ajax({
        type: 'POST',
        url: 'http://www.mysite.com/handler-question.php',
        dataType: 'json',
        data: $(this).data('object'),
        success: function(data) {

            $('.quiz').html('<div class="content">'
                + '<div class="widget six sign">'
                    + '<img src="http://www.mysite.com/images/questions/'+data[0].que_file+'" alt="">'
                + '</div>'
                + '<div class="widget six question">'
                    + '<header>'
                          + '<button class="align-right button" data-object='+'{"qui_id":"'+data[0].qui_id+'","action":"1","que_id":"'+data[0].que_id+'"}'+'>Skip</button>'
                    + '</header>'
                    + '<h2>Q: '+data[0].que_question+'</h2>'
                + '</div>'
                + '<div class="widget twelve answers">'
                    + '<ul>'
                         + '<li><button data-object='+'{"ans_id":"'+data[1].ans_id+'"}'+'>A: '+data[1].ans_answer+'</button></li>'
                         + '<li><button data-object='+'{"ans_id":"'+data[2].ans_id+'"}'+'>B: '+data[2].ans_answer+'</button></li>'
                         + '<li><button data-object='+'{"ans_id":"'+data[3].ans_id+'"}'+'>C: '+data[3].ans_answer+'</button></li>'
                         + '<li><button data-object='+'{"ans_id":"'+data[4].ans_id+'"}'+'>D: '+data[4].ans_answer+'</button></li>'
                    + '</ul>'
                + '</div>'  
                + '<div class="widget six navigation">'
                    + '<button class="align-right button" data-object='+'{"qui_id":"'+data[0].qui_id+'","action":"0","que_id":"'+data[0].que_id+'"}'+'>Next</button>'
                + '</div>'
                + '</div>');

        }
    }); 
}); 

Ajax 调用没问题

$('.question,.navigation').on('click', '.button', function() {

    $.ajax({
        type: 'POST',
        url: 'http://www.mysite.com/handler-question.php',
        dataType: 'json',
        data: $(this).data('object'),
        success: function(data) {

            $('.sign').html('<img src="http://www.mysite.com/images/questions/'+data[0].que_file+'" alt="">');

            $('.question').html('<header>'
                + '<button class="align-right button" data-object='+'{"qui_id":"'+data[0].qui_id+'","action":"1","que_id":"'+data[0].que_id+'"}'+'>Skip</button>'
                + '</header>'
                + '<h2>Q: '+data[0].que_question+'</h2>');

            $('.answers').html('<ul>'
                + '<li><button data-object='+'{"ans_id":"'+data[1].ans_id+'"}'+'>A: '+data[1].ans_answer+'</button></li>'
                + '<li><button data-object='+'{"ans_id":"'+data[2].ans_id+'"}'+'>B: '+data[2].ans_answer+'</button></li>'
                + '<li><button data-object='+'{"ans_id":"'+data[3].ans_id+'"}'+'>C: '+data[3].ans_answer+'</button></li>'
                + '<li><button data-object='+'{"ans_id":"'+data[4].ans_id+'"}'+'>D: '+data[4].ans_answer+'</button></li>'
                + '</ul>'); 

                $('.navigation').html('<button class="align-right button" data-object='+'{"qui_id":"'+data[0].qui_id+'","action":"0","que_id":"'+data[0].que_id+'"}'+'>Next</button>');

        }
    }); 
}); 

【问题讨论】:

  • 你真的需要在 jQuery 中生成所有的 HTML 吗?为什么不静态创建大部分数据,然后用动态数据替换您需要的位?

标签: javascript jquery html ajax dom


【解决方案1】:

如果您将内容替换为html(),则所有附加到元素的事件侦听器都会丢失,即使您再次重新创建相同的标记也是如此。事实上,侦听器仍在内存中,并且会占用浏览器的 RAM,但这是另一回事。

你有两种可能:

  1. 替换 html 内容后重新创建事件侦听器。因此,您应该将整个点击侦听器回调分配给一个变量。但这不是最可维护和最优雅的解决方案。

  2. 如果可能,不要破坏仍将使用的元素。相反,只需修改已更改的元素(如您的第二个工作示例中)。这样你甚至可以使用一些高亮动画来通知用户更新。

另外,我赞同 net.uk.sweet 在评论部分所说的:生成 html 应该与您的 ajax javascript 处理分开。只需更新必要的位。

【讨论】:

  • 这是个好建议,但为什么第一个例子不起作用,而第二个例子起作用?
  • 因为第一个示例从分离事件侦听器的 dom 中删除了 .question.navigation 元素,而第二个示例没有,因为仅替换了这些元素的内部内容
  • @Alp 非常感谢,这是有道理的。是的,我正在使用我的第二个示例,我只是想知道为什么第一个不起作用,但现在这很有意义。非常感谢您的宝贵时间,非常感谢!
猜你喜欢
  • 1970-01-01
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-28
  • 2016-05-27
  • 1970-01-01
  • 2015-01-05
相关资源
最近更新 更多