Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

133
Views
jQuery click unbound after Ajax call that modifies page HTML using html() method of page element

I am using jQuery v3.6.0 on a page that should dynamically allow a user to bookmark/unbookmark an item displayed on the page.

Here is my code snippet:

HTML

<div id="37.3" class="social-info-container">
   <div id="VK7n" class="social bookmarkable">
    <i title="Bookmarks" class="fa fa-bookmark"></i>0
   </div>
</div>

Javascript

function bookmarkItem(id, elem_id){
  let [ctid, oid] = id.split('.');
    console.log(`Posting bookmark for item with content_type: ${ctid}, object_id: ${oid}`);

    $.ajax({
        type: "POST",
    headers:{'X-CSRFToken': special_csrf_token },
        url: social_bookmark_url,
        data: {
            cid: ctid,
            oid: oid,
      note: ''
        },
        dataType: "json",
        success: function(resultData) {
      console.log(`Reponse ok: ${resultData.ok}`);
      console.log(`Elem id: ${elem_id}`);
      $(`div#${elem_id}.social.bookmarkable > i.fa.fa-bookmark`).toggleClass('bookmarked');
      
      let orig_html = $(`div#${elem_id}`).html();
      let old_count = $(`div#${elem_id}`).text();
      let new_count = resultData.count; 
      let new_html = orig_html.replace(old_count,new_count)

      console.log(old_count);
      console.log(orig_html);
      console.log(new_count);

      console.log(new_html);

      $(`div#${elem_id}`).html(new_html);
        },
        error: function(xhr, status, error) {
            if (xhr.status == 403){
        window.location.href = login_url;
      }
      else {
        alert(`Something went wrong: ${xhr.statusText}`);
      }
        }
    });  
}

$().ready(function(){
    $('.social.bookmarkable .fa.fa-bookmark').on('click', function(e) {
      alert('Clicked!');
      let elem_id = $(this).closest('div.social.bookmarkable').attr('id');

      console.log(`Elem id (1): ${elem_id}`);
      let id = $(this).closest('div.social-info-container').attr('id');
      bookmarkItem(id, elem_id);
    });
});

When I click the bookmark icon, it works ONCE - after that I have to refresh the page to get it to work again. I thought using the on() method to bind to the click event would avoid this problem.

Why is the event being triggered just once - and how do I fix this?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

You're replacing the element that the event handler is bound to. Using .on() will only work if the element you bind it to is still around. You need to also delegate the handler to an element that will always exist, and then use eg selector context to filter for the element you want.

function bookmarkItem(id, elem_id) {
    let [ctid, oid] = id.split('.');
    console.log(`Posting bookmark for item with content_type: ${ctid}, object_id: ${oid}`);
    
    // Fake response to the AJAX call
    let resultData = {
        ok: 'ok',
        count: 1
    };

    $(`div#${elem_id}.social.bookmarkable > i.fa.fa-bookmark`).toggleClass('bookmarked');

    let orig_html = $(`div#${elem_id}`).html();
    let old_count = $(`div#${elem_id}`).text();
    let new_count = resultData.count;
    let new_html = orig_html.replace(old_count,new_count)

    console.log('old_count', old_count);
    console.log('orig_html', orig_html);
    console.log('new_count', new_count);
    console.log('new_html', new_html);

    $(`div#${elem_id}`).html(new_html);
}

$().ready(function(){
    // Attach handler to an element which does not go away, and filter
    // to only match clicks on the element you want. 
    // https://api.jquery.com/jquery/#selector-context
    $('.social.bookmarkable').on('click', '.fa.fa-bookmark', function(e) {
        let elem_id = $(this).closest('div.social.bookmarkable').attr('id');
        let id = $(this).closest('div.social-info-container').attr('id');
        
        console.log('Bookmark clicked: elem_id', elem_id, '; id', id);
        
        bookmarkItem(id, elem_id);
    });
});
.bookmarked {
    background-color: black;
    color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="37.3" class="social-info-container">
   <div id="VK7n" class="social bookmarkable">
    <i title="Bookmarks" class="fa fa-bookmark">Click me</i>0
   </div>
</div>

There are many examples of this here on SO already, searching for keywords like "jquery only once", or "jquery replace handler once" turns them up. I know this well bcs I've done that search in the past :-) Eg:

  • jQuery - `on` event doesn't work after jQuery.replaceWith
  • jquery click only firing once
  • JQuery click event works only once
  • Jquery .change() event fires only once
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!