Adjuntar evento a elementos dinámicos en javascript

6 minutos de lectura

Adjuntar evento a elementos dinamicos en javascript
Manju

Estoy tratando de insertar datos html dinámicamente en una lista que se crea dinámicamente, pero cuando intento adjuntar un evento onclick para el botón que se crea dinámicamente, el evento no se activa. La solución sería muy apreciada.

Código JavaScript:

document.addEventListener('DOMContentLoaded', function () {
   document.getElementById('btnSubmit').addEventListener('click', function () {
        var name = document.getElementById('txtName').value;
        var mobile = document.getElementById('txtMobile').value;
        var html="<ul>";
        for (i = 0; i < 5; i++) {
            html = html + '<li>' + name + i + '</li>';
        }
        html = html + '</ul>';

        html = html + '<input type="button" value="prepend" id="btnPrepend" />';
        document.getElementsByTagName('form')[0].insertAdjacentHTML('afterend', html);
    });

    document.getElementById('btnPrepend').addEventListener('click', function () {
        var html="<li>Prepending data</li>";
        document.getElementsByTagName('ul')[0].insertAdjacentHTML('afterbegin', html);
    });
});

Código HTML:

<form>
    <div class="control">
        <label>Name</label>
        <input id="txtName" name="txtName" type="text" />
    </div>
    <div class="control">
        <label>Mobile</label>
        <input id="txtMobile" type="text" />
    </div>
    <div class="control">
        <input id="btnSubmit" type="button" value="submit" />
    </div>
</form>

  • ¿Cómo estás creando el html?

    – jim0thy

    20 de enero de 2016 a las 9:29

  • Diría que es porque el elemento no existe cuando intenta adjuntar el detector de eventos. – Echa un vistazo a esto learn.jquery.com/events/event-delegación

    – galleta

    20 de enero de 2016 a las 9:31


  • Mueva su addEventListener al detector de eventos de btnSubmit

    – durmiente

    20 de enero de 2016 a las 9:34

  • Oye, solo quería mencionar que parece que estás tratando de crear un elemento ul con elementos li dentro de él de una manera difícil. En su lugar, podría usar “ (comillas invertidas) y colocar los elementos de la forma en que lo haría normalmente en HTML.

    – Dan

    21 de marzo de 2021 a las 20:46

1646956988 461 Adjuntar evento a elementos dinamicos en javascript
jilykate

Esto se debe al hecho de que su elemento se crea dinámicamente. Debe usar la delegación de eventos para manejar el evento.

 document.addEventListener('click',function(e){
    if(e.target && e.target.id== 'brnPrepend'){
          //do something
     }
 });

jquery lo hace más fácil:

 $(document).on('click','#btnPrepend',function(){//do something})

Aquí hay un artículo sobre la delegación de eventos. artículo de delegación de eventos

  • ¡Gracias! A veces, la solución JS pura no funciona en iPhone, pero si cambia el documento en otro div principal, por ejemplo, funciona. ¿Cuál es la mejor solución para la delegación?

    – Joliavko

    10 mayo 2017 a las 14:16

  • @Kholiavko Diría que siempre que el elemento “principal” no se cree dinámicamente, debería funcionar. Vincularía el controlador de eventos al primer padre del elemento de creación dinámica d para que no haya conflictos entre los diferentes controladores de eventos

    – jilykate

    11 de mayo de 2017 a las 7:47


  • Pero a veces no funciona en iPhone, incluso el elemento “principal” no se crea dinámicamente. Aquí está ejemplo, funciona en todos los navegadores, pero no en iPhone (safary e incluso Chrome). Y no entiendo por qué.

    – Joliavko

    11 de mayo de 2017 a las 9:57


  • @Kholiavko esto es solo porque codepen usa un sandbox para envolver todo. Si realmente escribe ese código en una página normal, funcionará

    – jilykate

    11 de mayo de 2017 a las 13:04

  • Considere agregar un signo igual adicional (===) para evitar la coerción de tipo inesperada

    – Staccato

    4 sep 2019 a las 20:54

Adjuntar evento a elementos dinamicos en javascript
daniel manasov

Existe una solución al capturar los clics en document.body y luego verificando el objetivo del evento.

document.body.addEventListener( 'click', function ( event ) {
  if( event.target.id == 'btnSubmit' ) {
    someFunc();
  };
} );

  • O contenedor más cercano

    – mplungjan

    20 de agosto de 2019 a las 12:09

  • ¡Respuesta perfecta!

    – Raúl Purohit

    1 de agosto de 2020 a las 15:34

  • ¡GUAU, esto es increíble, ahorra mucho tiempo y código! 🙂

    – Anna Medyukh

    6 sep 2020 a las 14:17

  • Nota: event.srcElement está en desuso. Se recomienda usar event.target en su lugar.

    – dsanchez

    23 oct 2020 a las 16:18

La diferencia está en cómo creas y agregas elementos en el DOM.

Si crea un elemento a través de document.createElement, agregue un detector de eventos y agréguelo al DOM. Tus eventos se dispararán.

Si crea un elemento como una cadena como esta: html += “

  • test
  • “`, el elemento es técnicamente solo una cadena. Las cadenas no pueden tener detectores de eventos.

    Una solución es crear cada elemento con document.createElement y luego agréguelos a un elemento DOM directamente.

    // Sample
    let li = document.createElement('li')
    document.querySelector('ul').appendChild(li)
    

    1646956989 313 Adjuntar evento a elementos dinamicos en javascript
    R3tep

    Debe adjuntar el evento después de insertar elementos, así no adjunta un evento global en su document sino un evento específico sobre los elementos insertados.

    p.ej

    document.getElementById('form').addEventListener('submit', function(e) {
      e.preventDefault();
      var name = document.getElementById('txtName').value;
      var idElement="btnPrepend";
      var html = `
        <ul>
          <li>${name}</li>
        </ul>
        <input type="button" value="prepend" id="${idElement}" />
      `;
      /* Insert the html into your DOM */
      insertHTML('form', html);
      /* Add an event listener after insert html */
      addEvent(idElement);
    });
    
    const insertHTML = (tag = 'form', html, position = 'afterend', index = 0) => {
      document.getElementsByTagName(tag)[index].insertAdjacentHTML(position, html);
    }
    const addEvent = (id, event="click") => {
      document.getElementById(id).addEventListener(event, function() {
        insertHTML('ul', '<li>Prepending data</li>', 'afterbegin')
      });
    }
    <form id="form">
      <div>
        <label for="txtName">Name</label>
        <input id="txtName" name="txtName" type="text" />
      </div>
      <input type="submit" value="submit" />
    </form>

    Puedes hacer algo similar a esto:

    // Get the parent to attatch the element into
    var parent = document.getElementsByTagName("ul")[0];
    
    // Create element with random id
    var element = document.createElement("li");
    element.id = "li-"+Math.floor(Math.random()*9999);
    
    // Add event listener
    element.addEventListener("click", EVENT_FN);
    
    // Add to parent
    parent.appendChild(element);
    

    Adjuntar evento a elementos dinamicos en javascript
    paranjothi

    var __ = function(){
        this.context  = [];
        var self = this;
        this.selector = function( _elem, _sel ){
            return _elem.querySelectorAll( _sel );
        }
              this.on = function( _event, _element, _function ){
                  this.context = self.selector( document, _element );
                  document.addEventListener( _event, function(e){
                      var elem = e.target;
                      while ( elem != null ) {
                          if( "#"+elem.id == _element || self.isClass( elem, _element ) || self.elemEqal( elem ) ){
                              _function( e, elem );
                          }
                          elem = elem.parentElement;
                      }
                  }, false );
         };
    
         this.isClass = function( _elem, _class ){
            var names = _elem.className.trim().split(" ");
            for( this.it = 0; this.it < names.length; this.it++ ){
                names[this.it] = "."+names[this.it];
            }
            return names.indexOf( _class ) != -1 ? true : false;
        };
    
        this.elemEqal = function( _elem ){
            var flg = false;
            for( this.it = 0; this.it < this.context.length;  this.it++ ){
                if( this.context[this.it] === _elem && !flg ){
                    flg = true;
                }
            }
            return flg;
        };
    
    }
    
        function _( _sel_string ){
            var new_selc = new __( _sel_string );
            return new_selc;
        }
    

    Ahora puede registrar eventos como,

    _( document ).on( "click", "#brnPrepend", function( _event, _element ){
          console.log( _event );
          console.log( _element );
          // Todo
    
      });
    

    Compatibilidad con navegador

    Chrome – 4.0, Edge – 9.0, Firefox – 3.5 Safari – 3.2, Opera – 10.0 y superior

    1646956991 711 Adjuntar evento a elementos dinamicos en javascript
    XCS

    He creado una pequeña biblioteca para ayudar con esto: Fuente de la biblioteca en GitHub

    <script src="https://stackoverflow.com/questions/34896106/dynamicListener.min.js"></script>
    <script>
    // Any `li` or element with class `.myClass` will trigger the callback, 
    // even elements created dynamically after the event listener was created.
    addDynamicEventListener(document.body, 'click', '.myClass, li', function (e) {
        console.log('Clicked', e.target.innerText);
    });
    </script>
    

    La funcionalidad es similar a jQuery.on().

    La biblioteca utiliza el Elemento.coincidencias() método para probar el elemento de destino contra el selector dado. Cuando se activa un evento, la devolución de llamada solo se llama si el elemento de destino coincide con el selector dado.

    ¿Ha sido útil esta solución?

    Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
    Privacidad