obtiene objetos objeto forma eventos evento elementos div dinámicamente dinámica dinamicos dinamicamente crear creados creado con como asociar asignar acceso javascript jquery events unobtrusive-javascript

javascript - objetos - eventos elementos dinamicos jquery



¿Enlace de eventos en elementos creados dinámicamente? (23)

Tengo un poco de código en el que hago un bucle a través de todos los cuadros de selección en una página y los .hover un evento .hover para hacer un poco de maniobra con su ancho en el mouse on/off .

Esto sucede en la página lista y funciona bien.

El problema que tengo es que los cuadros de selección que agregué a través de Ajax o DOM después del bucle inicial no tendrán el evento enlazado.

He encontrado este complemento ( jQuery Live Query Plugin ), pero antes de agregar otros 5k a mis páginas con un complemento, quiero ver si alguien sabe una forma de hacerlo, ya sea directamente con jQuery o por otra opción.


Enlace de eventos en elementos creados dinámicamente

Elemento único:

$(document.body).on(''click'',''.element'', function(e) { });

Elemento hijo:

$(document.body).on(''click'',''.element *'', function(e) { });

Note el agregado * . Se activará un evento para todos los hijos de ese elemento.

Me he dado cuenta que:

$(document.body).on(''click'',''.#element_id > element'', function(e) { });

Ya no funciona, pero funcionaba antes. He estado usando jQuery de Google CDN , pero no sé si lo cambiaron.


Aquí es por qué los elementos creados dinámicamente no responden a los clics:

var body = $("body"); var btns = $("button"); var btnB = $("<button>B</button>"); // `<button>B</button>` is not yet in the document. // Thus, `$("button")` gives `[<button>A</button>]`. // Only `<button>A</button>` gets a click listener. btns.on("click", function () { console.log(this); }); // Too late for `<button>B</button>`... body.append(btnB);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button>A</button>

Como solución alternativa, debe escuchar todos los clics y verificar el elemento de origen:

var body = $("body"); var btnB = $("<button>B</button>"); var btnC = $("<button>C</button>"); // Listen to all clicks and // check if the source element // is a `<button></button>`. body.on("click", function (ev) { if ($(ev.target).is("button")) { console.log(ev.target); } }); // Now you can add any number // of `<button></button>`. body.append(btnB); body.append(btnC);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button>A</button>

Esto se llama "Delegación de eventos". Buenas noticias, es una característica incorporada en jQuery :-)

var i = 11; var body = $("body"); body.on("click", "button", function () { var letter = (i++).toString(36).toUpperCase(); body.append($("<button>" + letter + "</button>")); });

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button>A</button>


Cualquier declaración que exista en el momento en que el evento esté vinculado y si su página estaba creando elementos dinámicamente con el botón de nombre de clase, vincularía el evento a un padre que ya existe

$(document).ready(function(){ //Particular Parent chield click $(".buttons").on("click","button",function(){ alert("Clicked"); }); //Dynamic event bind on button class $(document).on("click",".button",function(){ alert("Dymamic Clicked"); }); $("input").addClass("button"); });

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div class="buttons"> <input type="button" value="1"> <button>2</button> <input type="text"> <button>3</button> <input type="button" value="5"> </div> <button>6</button>


Enlace el evento a un padre que ya existe:

$(document).on("click", "selector", function() { // Your code here });


Esta es una solución de JavaScript pura sin bibliotecas ni complementos:

document.addEventListener(''click'', function (e) { if (hasClass(e.target, ''bu'')) { // .bu clicked // Do your thing } else if (hasClass(e.target, ''test'')) { // .test clicked // Do your other thing } }, false);

donde hasClass es

function hasClass(elem, className) { return elem.className.split('' '').indexOf(className) > -1; }

Demo en vivo

El crédito es para Dave y Sime Vidas.

Usando JS más moderno, hasClass puede implementarse como:

function hasClass(elem, className) { return elem.classList.contains(className); }


Estaba buscando una solución para que $.bind y $.unbind funcionen sin problemas en elementos agregados dinámicamente.

Como on() hace el truco para adjuntar eventos, para crear un desvinculación falsa en aquellos a los que llegué:

const sendAction = function(e){ ... } // bind the click $(''body'').on(''click'', ''button.send'', sendAction ); // unbind the click $(''body'').on(''click'', ''button.send'', function(){} );


Esto se hace por delegación de eventos. El evento se enlazará en el elemento de la clase contenedora, pero se delegará en el elemento de la clase selectora. Así es como funciona.

$(''.wrapper-class'').on("click", ''.selector-class'', function() { // Your code here });

Nota:

El elemento clase envoltura puede ser cualquier cosa, por ejemplo. Documento, cuerpo o envoltorio. La envoltura ya debería existir.


Hay una buena explicación en la documentación de on() .

En breve:

Los controladores de eventos están vinculados solo a los elementos seleccionados actualmente; deben existir en la página en el momento en que su código realiza la llamada a .on() .

Así, en el siguiente ejemplo, #dataTable tbody tr debe existir antes de que se genere el código.

$("#dataTable tbody tr").on("click", function(event){ console.log($(this).text()); });

Si se está inyectando nuevo HTML en la página, es preferible usar eventos delegados para adjuntar un controlador de eventos, como se describe a continuación.

Los eventos delegados tienen la ventaja de que pueden procesar eventos de elementos descendientes que se agregan al documento en un momento posterior. Por ejemplo, si la tabla existe, pero las filas se agregan dinámicamente utilizando el código, lo siguiente lo manejará:

$("#dataTable tbody").on("click", "tr", function(event){ console.log($(this).text()); });

Además de su capacidad para manejar eventos en elementos descendientes que aún no se han creado, otra ventaja de los eventos delegados es su potencial para una sobrecarga mucho menor cuando se deben monitorear muchos elementos. En una tabla de datos con 1,000 filas en su tbody , el primer ejemplo de código adjunta un controlador a 1,000 elementos.

Un enfoque de eventos delegados (el segundo ejemplo de código) adjunta un controlador de eventos a un solo elemento, el tbody , y el evento solo necesita aumentar un nivel (desde el tr click hasta el tbody ).

Nota: Los eventos delegados no funcionan para SVG .


Intenta así ...

$(document).on( ''click'', ''.click-activity'', function () { ... });


Intente usar .live() lugar de .bind() ; el .live() .hover a su casilla de verificación después de que se ejecute la solicitud Ajax.


Otra solución es agregar el oyente al crear el elemento. En lugar de poner al oyente en el cuerpo, pones el oyente en el elemento en el momento en que lo creas:

var myElement = $(''<button/>'', { text: ''Go to Google!'' }); myElement.bind( ''click'', goToGoogle); myElement.append(''body''); function goToGoogle(event){ window.location.replace("http://www.google.com"); }


Prefiero que los oyentes de eventos se implementen de una manera modular en lugar de hacer scripts a un oyente de eventos a nivel de document . Por lo tanto, me gusta a continuación. Tenga en cuenta que no puede sobrescribir un elemento con el mismo detector de eventos, así que no se preocupe por adjuntar un escucha más de una vez, solo una pega.

var iterations = 4; var button; var body = document.querySelector("body"); for (var i = 0; i < iterations; i++) { button = document.createElement("button"); button.classList.add("my-button"); button.appendChild(document.createTextNode(i)); button.addEventListener("click", myButtonWasClicked); body.appendChild(button); } function myButtonWasClicked(e) { console.log(e.target); //access to this specific button }


Prefiero usar el selector y lo aplico en el documento.

Esto se enlaza con el documento y se aplicará a los elementos que se representarán después de cargar la página.

Por ejemplo:

$(document).on("click", $(selector), function() { // Your code here });


Puede adjuntar evento a elemento cuando se crea dinámicamente usando jQuery(html, attributes) .

A partir de jQuery 1.8 , cualquier método de instancia de jQuery (un método de jQuery.fn ) se puede usar como una propiedad del objeto pasado al segundo parámetro:

function handleDynamicElementEvent(event) { console.log(event.type, this.value) } // create and attach event to dynamic element jQuery("<select>", { html: $.map(Array(3), function(_, index) { return new Option(index, index) }), on: { change: handleDynamicElementEvent } }) .appendTo("body");

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> </script>


Puede utilizar el método live () para vincular elementos (incluso los recién creados) a eventos y controladores, como el evento onclick.

Aquí hay un código de muestra que he escrito, donde puede ver cómo el método live () vincula los elementos seleccionados, incluso los creados recientemente, a los eventos:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Untitled Document</title> </head> <body> <script src="http://code.jquery.com/jquery-latest.js"></script> <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js"></script> <input type="button" id="theButton" value="Click" /> <script type="text/javascript"> $(document).ready(function() { $(''.FOO'').live("click", function (){alert("It Works!")}); var $dialog = $(''<div></div>'').html(''<div id="container"><input type ="button" id="CUSTOM" value="click"/>This dialog will show every time!</div>'').dialog({ autoOpen: false, tite: ''Basic Dialog'' }); $(''#theButton'').click(function() { $dialog.dialog(''open''); return(''false''); }); $(''#CUSTOM'').click(function(){ //$(''#container'').append(''<input type="button" value="clickmee" class="FOO" /></br>''); var button = document.createElement("input"); button.setAttribute(''class'',''FOO''); button.setAttribute(''type'',''button''); button.setAttribute(''value'',''CLICKMEE''); $(''#container'').append(button); }); /* $(''#FOO'').click(function(){ alert("It Works!"); }); */ }); </script> </body> </html>


Puedes agregar eventos a los objetos cuando los creas. Si está agregando los mismos eventos a múltiples objetos en diferentes momentos, la creación de una función con nombre podría ser el camino a seguir.

var mouseOverHandler = function() { // Do stuff }; var mouseOutHandler = function () { // Do stuff }; $(function() { // On the document load, apply to existing elements $(''select'').hover(mouseOverHandler, mouseOutHandler); }); // This next part would be in the callback from your Ajax call $("<select></select>") .append( /* Your <option>s */ ) .hover(mouseOverHandler, mouseOutHandler) .appendTo( /* Wherever you need the select box */ ) ;


Simplemente podría ajustar su llamada de enlace de evento en una función y luego invocarla dos veces: una vez en el documento listo y una vez después de su evento que agrega los nuevos elementos DOM. Si lo hace, querrá evitar vincular el mismo evento dos veces en los elementos existentes, por lo que necesitará desvincular los eventos existentes o (mejor) vincular solo a los elementos DOM que se crean recientemente. El código se vería algo así:

function addCallbacks(eles){ eles.hover(function(){alert("gotcha!")}); } $(document).ready(function(){ addCallbacks($(".myEles")) }); // ... add elements ... addCallbacks($(".myNewElements"))


Tome nota de la clase "PRINCIPAL" en que se coloca el elemento, por ejemplo,

<div class="container"> <ul class="select"> <li> First</li> <li>Second</li> </ul> </div>

En el escenario anterior, el objeto PRINCIPAL que observará jQuery es "contenedor".

Luego, básicamente, tendrá nombres de elementos debajo del contenedor, como ul , li , y select :

$(document).ready(function(e) { $(''.container'').on( ''click'',".select", function(e) { alert("CLICKED"); }); });


Utilice el método .on() de jQuery on() para adjuntar controladores de eventos al elemento vivo.

También a partir de la versión 1.9 se .live() método .live() .


podrías usar

$(''.buttons'').on(''click'', ''button'', function(){ // your magic goes here });

o

$(''.buttons'').delegate(''button'', ''click'', function() { // your magic goes here });

Estos dos métodos son equivalentes pero tienen un orden diferente de parámetros.

ver: jQuery Delegate Event


A partir de jQuery 1.7 debe usar jQuery.fn.on :

$(staticAncestors).on(eventName, dynamicChild, function() {});

Antes de esto , el enfoque recomendado era usar live() :

$(selector).live( eventName, function(){} );

Sin embargo, live() quedó en desuso en 1.7 a favor de on() y se eliminó por completo en 1.9. La firma en live() :

$(selector).live( eventName, function(){} );

... se puede reemplazar con la siguiente firma on() :

$(document).on( eventName, selector, function(){} );

Por ejemplo, si su página creaba elementos dinámicamente con el nombre de clase dosomething , vincularía el evento a un padre que ya existe (este es el nudo del problema aquí, necesita algo para vincularlo, no vincularlo) El contenido dinámico), esto puede ser (y la opción más fácil) es document . Aunque tener en cuenta el document puede no ser la opción más eficiente .

$(document).on(''mouseover mouseout'', ''.dosomething'', function(){ // what you want to happen when mouseover and mouseout // occurs on elements that match ''.dosomething'' });

Cualquier padre que exista en el momento en que el evento esté vinculado está bien. Por ejemplo

$(''.buttons'').on(''click'', ''button'', function(){ // do something here });

se aplicaría a

<div class="buttons"> <!-- <button>s that are generated dynamically and added here --> </div>


Solución más flexible para crear elementos y eventos de enlace ( source )

// creating a dynamic element (container div) var $div = $("<div>", {id: ''myid1'', class: ''myclass''}); //creating a dynamic button var $btn = $("<button>", { type: ''button'', text: ''Click me'', class: ''btn'' }); // binding the event $btn.click(function () { //for mouseover--> $btn.on(''mouseover'', function () { console.log(''clicked''); }); // append dynamic button to the dynamic container $div.append($btn); // add the dynamically created element(s) to a static element $("#box").append($div);

Nota: Esto creará una instancia de controlador de eventos para cada elemento (puede afectar el rendimiento cuando se usa en bucles)


<html> <head> <title>HTML Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script> </head> <body> <div id="hover-id"> Hello World </div> <script> jQuery(document).ready(function($){ $(document).on(''mouseover'', ''#hover-id'', function(){ $(this).css(''color'',''yellowgreen''); }); $(document).on(''mouseout'', ''#hover-id'', function(){ $(this).css(''color'',''black''); }); }); </script> </body> </html>