Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

134
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda