$ (documento) .on ("hacer clic" ... ¿no funciona?

82

¿Hay algún error bien conocido que pueda estar cometiendo aquí?

Tengo un script que usa .on () porque un elemento se genera dinámicamente y no funciona. Solo para probarlo, reemplacé el selector con el ajuste del elemento dinámico, que es estático, ¡y todavía no funcionó! Sin embargo, cuando cambié a .click antiguo simple para la envoltura, funcionó.
(Esto simplemente no funcionará para el elemento dinámico obviamente, el que importa).

Esto funciona:

$("#test-element").click(function() {
    alert("click");
});

Esto no:

$(document).on("click","#test-element",function() {
    alert("click");
});

ACTUALIZAR:

Hice clic derecho e hice "Inspeccionar elemento" en Chrome para simplemente verificar algo, y luego el evento de clic funcionó. Actualicé y no funcionó, inspeccioné el elemento y luego funcionó. ¿Qué significa esto?

Sr. Lavalamp
fuente
1
¿Está creando más de un elemento con el mismo ID?
Adeneo
Publicar solo jQuery sin el HTML relevante dificulta la ayuda.
jmoerdyk
3
Hola OP, verifique la versión de Jquery que está usando, :)o mueva un violín que podría ayudarlo,
Tats_innit
Se supone que tu código funciona. La onfunción se agregó en jquery 1.7, asegúrese de tener una versión reciente. Editar: prueba para ti de que funciona en el violín
Phil-R
Su segundo ejemplo funciona con la última versión 1.x de jQuery: jsfiddle.net/AJPdS
Wookai

Respuestas:

153

Está utilizando la sintaxis correcta para vincular el documento a escuchar un evento de clic para un elemento con id = "test-element".

Probablemente no esté funcionando debido a uno de:

  • No usa la versión reciente de jQuery
  • No envolver su código dentro de DOM listo
  • o está haciendo algo que hace que el evento no llegue al oyente en el documento.

Para capturar eventos en elementos que se crean DESPUÉS de declarar sus oyentes de eventos, debe vincularse a un elemento principal o elemento superior en la jerarquía.

Por ejemplo:

$(document).ready(function() {
    // This WILL work because we are listening on the 'document', 
    // for a click on an element with an ID of #test-element
    $(document).on("click","#test-element",function() {
        alert("click bound to document listening for #test-element");
    });

    // This will NOT work because there is no '#test-element' ... yet
    $("#test-element").on("click",function() {
        alert("click bound directly to #test-element");
    });

    // Create the dynamic element '#test-element'
    $('body').append('<div id="test-element">Click mee</div>');
});

En este ejemplo, solo se activará la alerta "vinculado al documento".

JSFiddle con jQuery 1.9.1

itsmejodie
fuente
Desafortunadamente, estoy usando una versión reciente de Jquery, mi código está correctamente empaquetado, está dentro de $ (document) .ready y el evento en el que se hace clic es el elemento de nivel más bajo en el documento. Esto es desconcertante.
Sr. Lavalamp
Yo diría que "la necesidad de poner al oyente en el elemento padre" no es esencial, aunque también lo recomiendo. El burbujeo es lo que permite que .on () funcione. Si no pudiéramos confiar en que el burbujeo supere al padre inmediato, no sería una gran solución.
iGanja
@iGanja: buen punto y, como sugieres, "necesidad" no es la palabra correcta, ya que hay otras formas menos ideales de lograr esto. Revisé mi respuesta.
itsmejodie
Si estoy usando "esto" para hacer referencia al objeto del elemento, ¿cómo puedo adjuntar su evento con el documento?
Ashish Joshi
1
@JasonGlisson, supongo que si bien tiene un oyente en el documento, hay un problema con el evento que no se propaga (al hacer clic en el botón) o la diferencia entre event.targety event.currentTargeten algún lugar de su código, pero hay muchos cosas que podría incluir la desactivación de eventos de puntero en el botón
itsmejodie
12

Tu código debería funcionar, pero soy consciente de que la respuesta no te ayuda. Puede ver un ejemplo funcional aquí (jsfiddle) .

Jquery:

$(document).on('click','#test-element',function(){
    alert("You clicked the element with and ID of 'test-element'");
});

Como alguien ya señaló, está usando una identificación en lugar de una clase. Si tiene más de un elemento en la página con una ID, jquery devolverá solo el primer elemento con esa ID . No habrá ningún error porque así es como funciona. Si este es el problema, notará que el evento de clic funciona para el primero, test-elementpero no para los siguientes.

Si esto no describe con precisión los síntomas del problema, entonces quizás su selector esté equivocado. Su actualización me lleva a creer que este es el caso debido a que inspeccionamos un elemento y luego hacemos clic en la página nuevamente y activamos el clic. Lo que podría estar causando esto es si coloca el detector de eventos en el real en documentlugar de test-element. Si es así, cuando haga clic fuera del documento y vuelva a encenderlo (como desde la ventana del desarrollador de regreso al documento), el evento se activará. Si este es el caso, también notará que el evento de clic se activa si hace clic entre dos pestañas diferentes (porque son dos diferentes documenty, por lo tanto, está haciendo clic en el documento.

Si ninguno de estos es la respuesta, publicar HTML contribuirá en gran medida a resolverlo.

smilebomb
fuente
4

Una publicación antigua, pero me encanta compartir ya que tengo el mismo caso pero finalmente supe el problema:

El problema es: Hacemos una función para trabajar con un elemento HTML especificado, pero el elemento HTML relacionado con esta función aún no se ha creado (porque el elemento se generó dinámicamente). Para que funcione, debemos hacer la función al mismo tiempo que creamos el elemento. Elemento primero que hacer una función relacionada con él.

Simplemente palabra, una función solo funcionará para el elemento que creó antes (él). Cualquier elemento que haya creado dinámicamente significa después de él.

Pero inspeccione esta muestra que no prestó atención al caso anterior:

<div class="btn-list" id="selected-country"></div>

Adjunto dinámicamente:

<button class="btn-map" data-country="'+country+'">'+ country+' </button>

Esta función funciona bien haciendo clic en el botón:

$(document).ready(function() {    
        $('#selected-country').on('click','.btn-map', function(){ 
        var datacountry = $(this).data('country'); console.log(datacountry);
    });
})

o puedes usar cuerpo como:

$('body').on('click','.btn-map', function(){ 
            var datacountry = $(this).data('country'); console.log(datacountry);
        });

compare con esto que no funciona:

$(document).ready(function() {     
$('.btn-map').on("click", function() { 
        var datacountry = $(this).data('country'); alert(datacountry);
    });
});

espero que ayude

Sulung Nugroho
fuente
Puede evitar usar $ (documento). Listo para esperar a que el elemento se agregue al DOM si en su lugar comienza con $ (documento) .on ("haga clic" ... $ (documento) .on ("haga clic", "# país-seleccionado", función () {});
Loren
3

Esto funciona:

<div id="start-element">Click Me</div>

$(document).on("click","#test-element",function() {
    alert("click");
});

$(document).on("click","#start-element",function() {
    $(this).attr("id", "test-element");
});

Aquí está el violín

iGanja
fuente
1
Ese no es un elemento generado dinámicamente, según la pregunta.
itsmejodie
@itsmejodie - de acuerdo, pero está vinculado dinámicamente al controlador de eventos. cambiar la identificación no es esencialmente diferente a agregar un elemento DOM.
iGanja
1

Prueba esto:

$("#test-element").on("click" ,function() {
    alert("click");
});

La forma del documento de hacerlo también es extraña. Eso tendría sentido para mí si se usara para un selector de clase, pero en el caso de una identificación, probablemente solo tenga un DOM inútil atravesando allí. En el caso del selector de id, obtienes ese elemento instantáneamente.

Eduárd Moldován
fuente
2
¿En qué se diferencia esto de $("#test-element").click(function() {?
Sushanth -
2
Debe usar .on () para vincular eventos a DOM generados dinámicamente; cualquier cosa que esté vinculada con .click () intentará vincularse cuando el documento esté listo, y si el dom no está presente, no sucederá nada.
JTravakh
2
Pero usar .onsin usar a selectores lo mismo que aplicar directamente el evento de clic en él
Sushanth -
1
Esta no es la respuesta correcta para la pregunta. Esto se vinculará directamente al elemento y, por lo tanto, no es adecuado cuando el elemento se ha generado dinámicamente.
itsmejodie
1
De hecho, he leído los documentos, pero la sección sobre rendimiento realmente no tiene nada que ver con los controladores de eventos delegados, y su código no es un controlador de eventos delegado.
adeneo