2009-04-22 7 views
13

Tengo un error de IE que no estoy seguro de cómo solucionarlo.IE7 y 8 no se activan jQuery haga clic en eventos para elementos anexados dentro de una tabla

Uso de jQuery Mover dinámicamente un menú para que aparezca en un elemento con el mouseover.

Mi código (simplificado) se ve algo como esto:

$j = jQuery.noConflict(); 

$j(document).ready(function() 
{ 
    //do something on the menu clicks 
    $j('div.ico').click(function() { alert($j(this).parent().html()); }); 

    setUpActions('#tableId', '#menuId'); 
}); 

//on mouseover set up the actions menu to appear on mouseover 
function setUpActions(tableSelector, menuSelector) 
{ 
    $j(tableSelector + ' div.test').mouseover(function() 
    { 
     //note that append will move the underlying 
     //DOM element with all events from it's old 
     //parent to the end of this one. 
     $j(this).append($j(menuSelector).show()); 
    }); 
} 

Este menú no parece registrar eventos correctamente para el menú después de que ha sido movido en IE7, IE8 e IE8-como-IE7 (sí MS, eso es realmente un 'nuevo motor de renderizado' en IE8, todos te creemos).

Funciona como se esperaba en todo lo demás.

Puedes ver el comportamiento en a basic demo here.

En la demo se pueden ver dos ejemplos de la cuestión:

  1. La imagen de fondo de las teclas deben cambiar en vuelo estacionario (hecho con un CSS: Selector de vuelo estacionario). Funciona en el primer mouseover pero luego persiste.
  2. El evento de clic no se activa; sin embargo, con las herramientas de desarrollo puede llamarlo de forma manual y todavía está suscrito.

Se puede ver (2) en las herramientas de dev de IE8:

  1. abierto page en IE8
  2. herramientas dev Abiertas
  3. Seleccionar "escritura" ficha y "consola" sub-pestaña
  4. Tipo: $j('#testFloat div.ico:first').click() para llamar manualmente a cualquier evento suscrito
  5. Habrá una alerta en la página

Esto significa que soy no perdiendo las suscripciones al evento, todavía están allí, IE no las llama cuando hago clic.

¿Alguien sabe por qué ocurre este error (que no sea solo por el venerable motor de IE)?

¿Hay una solución?

¿Podría ser algo que estoy haciendo mal que simplemente funciona como se espera en todo lo demás?

Respuesta

10

Extrañamente, aunque su evento de clics no se activa en IE, si lo cambia a mousedown o mouse arriba, funciona como era de esperar, aunque todavía tiene problemas con la imagen estacionario.

$j('div.ico').mouseup(function() { alert($j(this).parent().html()); }); 
+0

Buena solución: ¡eso funciona! A pesar de que ': hover' es originalmente una extensión de IE, creo que solo aceptaré que no funciona aquí. ¡Aclamaciones! – Keith

0

Recomiendo usar los eventos en vivo en lugar de los últimos jquery.

esta manera se puede obligar a los elementos de clase CSS que no han sido creadas al principio, pero se agregará la unión clic cuando se añaden los nuevos elementos:

http://docs.jquery.com/Events/live

+1

Gracias, buena idea, pero lo he intentado y no hace la diferencia. No he perdido el evento de clic - $ j ('selector'), haga clic en() en la línea de comando de javascript activará el evento que espero. La suscripción al evento jQuery ha sobrevivido a la mudanza, es solo que IE no parece llamarlo. El CSS: hover tiene los mismos síntomas. – Keith

+0

¿tiene una página de demostración que pueda ver? – Richard

+0

Sí - el enlace está en la pregunta. – Keith

1

IE no copia eventos a elementos añadidos dinámicamente al DOM.

Intente vincular su evento de clic una vez que haya agregado lo que necesita para estar atado o usar.live()

si está utilizando clone() recuerde pasar clone (verdadero) para solicitar explícitamente la copia de controladores de eventos.

var actionMenu = $j(menuSelector); 

//actionMenu is now an Instance of jQuery, not the DOM object 
//because jQuery is chainable 

actionMenu.hide(); 

// notice the clone(true) 

$j(this).append(actionMenu.clone(true)); 

jQuery es chainable, por lo que también se puede escribir esto en la sintaxis "jQuery" como:

var clone = $j(menuSelector) 
       .clone(true) 
       .css('background-color', $j(this).css('background-color')); 

$j(this).append(clone); 

No creo que necesita el mostrar/ocultar ya que ocurre tan rápido.

+0

Como puede ver en el ejemplo del código en la pregunta y en la demostración operativa a la que estoy enlazando, no estoy usando clone(). @ richard.grundy sugirió usar live(), pero eso no hace ninguna diferencia. Intentaré volver a vincular los eventos; veré si eso tiene algún efecto. – Keith

+0

Ahora probado: volver a vincular el evento click no lo soluciona. Puedo llamar el evento manualmente: vaya a mi demostración en línea, abra la consola de JavaScript de la herramienta de desarrollo IE8 y llame a $ j ('# testFloat div.ico'). Haga clic en() - la acción que he suscrito se activará. – Keith

+0

Mi ejemplo es un código simplificado: en la demostración en vivo, tengo una tabla mucho más grande y muchas secuencias de comandos más. No quiero clonar el elemento a menos que sea necesario. Pero lo he intentado y tiene el mismo problema: los elementos clonados pueden mantener el evento con live() o re-binding, pero eso no soluciona el problema inicial de IE que no registra los eventos reales de clic o de desplazamiento. – Keith

2

Tuve el mismo problema, pero ninguna de las soluciones anteriores funcionó. El problema resultó ser que IE7 (no he probado otras versiones de IE) no registrará el .click si está encadenado después de una función animada. Por lo que esto NO trabajo:

$("div.menubar-item").animate({ 
    color:"#000" 
}, 0) 

.click(function() 
{ 
    //not firing 
}) 

Pero esto VOLUNTAD trabajo

$("div.menubar-item").click(function() 
{ 
    //firing! 
}) 

$("div.menubar-item").animate({ 
    color:"#000" 
}, 0) 

EDITAR: Lo mismo es cierto para MouseEnter, mouseleave, etc.

EDIT 2: Todavía activará eventos y animará si encadena la función animada DESPUÉS del clic, por lo que s es "válido" también:

$("div.menubar-item").click(function() 
{ 
    //firing! 
}) 

.animate({ 
    color:"#000" 
}, 0) 
+0

¡WOW! Esto realmente funcionó. Al mover mi declaración de evento al inicio de mi gabinete, se solucionó el problema. EXTRAÑO. Nota para otros: estaba usando el evento .on(). – mrbinky3000

+1

ACTUALIZACIÓN: Investigué un poco más y descubrí que IE estaba encontrando un error ANTES de la declaración de mi evento y dejé de intentar analizar cualquier javascript pasado ese punto. Entonces, al mover el disparador de evento a la parte superior de mi script, solucioné el problema del disparador. Sin embargo, corregir el error en IE significaba que podía mover el activador de mi evento a su ubicación original y todo funcionaba bien. Moraleja de la historia: USE LAS HERRAMIENTAS DEL DESARROLLADOR DE IE. Verifique la consola para ver si hay errores. – mrbinky3000

+0

¡Genial! Buen hallazgo :-) – altschuler

Cuestiones relacionadas