简体   繁体   中英

jQuery Ajax call on click only works once

I'm building a quiz for a clients website and I'm getting the questions from an Ajax call and then replacing the HTML content with the new question, the problem is my Ajax call only is working once and then fails if I try it again. When I replace the content all at once with html() it fails, how ever if I break it down into sections and replace do html() for each section it works no problem but when I do it all at once if fails after the first time, if anyone could take a look at my code and tell me why this is happening it would be very much appreciated, thanks in advance!

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 Call only works once

$('.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 Call works no problem

$('.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>');

        }
    }); 
}); 

If you replace content with html() all event listeners attached to elements are lost, even if you are recreating the same markup again. In fact the listeners are still in memory and clutter up the RAM consumption of the browser, but that's a different story.

You have two possibilities:

  1. Recreate the event listeners once you replaced the html content. You should therefore assign the whole click listener callback to a variable. But this is not the most maintainable and elegant solution.

  2. If possible, do not destroy elements that will still be used. Instead, just modify the elements that have changed (like in your working second example). That way you can even use some highlighting animations to notify the user of the update.

Also, i second what net.uk.sweet said in the comment section: generating html should be separated from your ajax javascript handling. Just update the necessary bits.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM