2010-06-17 21 views
5

Hay un error en jQuery 1.4.2 que hace que el evento change en select-element se active dos veces cuando se usa tanto evento DOM como evento jQuery, y esto solo en IE7/8. Aquí está el código de prueba:Problema de jQuery con evento de cambio e IE8

<html> 

<head> 
    <script src="http://code.jquery.com/jquery-1.4.2.js" type="text/javascript"></script> 

    <script type="text/javascript"> 

     jQuery(document).ready(function() { 

     jQuery(".myDropDown").change(function() { 


     }); 

     }); 

    </script> 

</head> 

<body> 
    <select class="myDropDown" onchange="alert('hello');"> 
      <option>1</option> 
      <option>2</option> 
      <option>3</option> 
      <option>4</option> 
     </select> 
</body> 

</html> 

actualización: Otra vista del problema, de hecho este es el verdadero problema que tenemos con nuestra aplicación. Al vincular un evento de cambio en vivo en un selector que ni siquiera toca el elemento de selección con evento DOM, también se produce un doble disparo.

<html> 

<head> 
    <script src="http://code.jquery.com/jquery-1.4.2.js" type="text/javascript"></script> 

    <script type="text/javascript"> 

     jQuery(document).ready(function() { 

     jQuery(".someSelectThatDoesNotExist").live("change", function() { 


     }); 

     }); 

    </script> 

</head> 

<body> 
    <select class="myDropDown" onchange="alert('hello');"> 
      <option>1</option> 
      <option>2</option> 
      <option>3</option> 
      <option>4</option> 
     </select> 
</body> 

</html> 

entradas a error real: http://dev.jquery.com/ticket/6593

Esto causa un montón de problemas para nosotros en nuestra causa aplicación que usamos ambos ASP.NET-eventos mezclados con jQuery y una vez que conectar un evento de cambio en cualquier elemento cada selección (menú desplegable) obtiene este problema de doble disparo.

¿Hay alguien que sepa una forma de evitar esto hasta que se resuelva este problema?

+0

¿Necesita el caso de propagar? –

+0

Desafortunadamente, si necesita un comportamiento de propagación, etc. No creo que sea posible, este es un error de núcleo 1.4.2/IE8 que necesitará una comprobación adicional en el núcleo de jQuery para solucionarlo. –

+0

@Nick: ¿Qué quieres decir con propagate? Quiero que funcione como los otros navegadores, el evento solo dispara una vez. – Marcus

Respuesta

2

No me gusta plantear esta pregunta de la muerte, pero jquery finalmente corrigió este error en la versión 1.7 que se lanzó recientemente.

+0

Bien, gracias. Entonces eres el afortunado obteniendo una respuesta marcada :) – Marcus

0

algo como esto?

jQuery(".myDropDown").removeAttr('onchange').change(function() { 

alert(0); 
}); 
+0

Entonces no se disparaba en absoluto :) –

+0

ahhh ... hmmm ... ¿puedes decirme por qué es eso tan malo? ....;) bueno, no lo he intentado aunque .. – Reigel

+0

Claro :) Aquí hay una demostración, no dudes en probar tu código: http://jsfiddle.net/jfjBH/ El controlador 'onchange' es el que está disparando dos veces, si lo quitas, está apuntando a disparar. El error actual es que está recibiendo 2 alertas en IE8. Como regla general, no trate los atributos como eventos (incluso si están * declarados * de esa manera), no están * realmente * relacionados y solo funcionan en IE IIRC. –

1

que tenían un juego alrededor con el error y no parece haber ninguna solución obvia. En mis pruebas descubrí que el segundo evento de cambio es provocado por jQuery, así que logré juntar una solución rápida que implica eliminar el controlador de eventos DOM 0 y aplicarlo nuevamente en un temporizador que se ejecuta inmediatamente cuando termina la secuencia:

 jQuery(".myDropDown").change(function() { 
     if ($.browser.msie) { 
      var dd = $(this)[0], 
       oc = dd.onchange; 
      dd.onchange = null; 
      window.setTimeout(function() { 
       dd.onchange = oc; 
      }, 0); 
      } 
    }); 

Esto funciona bien para mí en IE8, solo aparece una alerta "hola", aunque es posible que desee agregar un IE check allí. O no, probablemente no hará la diferencia Definitivamente necesita ese control y lo he agregado a la muestra. Here's my fiddle.

La única otra solución sería eliminar el controlador DOM 0 y usar el controlador jQuery solamente.

0

realidad se resuelve el problema de otra manera, ya que este es específico para IE, ASP.NET y seleccione el elemento, se utiliza el siguiente código:

$(function() { 
if ($.browser.msie) { 
    var prm = Sys.WebForms.PageRequestManager.getInstance(); 
    prm.add_pageLoaded(function() { 
     $('select[onchange]:not(.iefixed)') 
      .addClass('iefixed') 
      .each(function() { 
       var self = $(this), dd = self[0], action = self.attr('onchange'); 
       self.removeAttr('onchange').change(action); 
       dd.onpropertychange = function() { dd.blur(); }; 
      }); 
    }); 
} 
}); 
  1. Este asegurarse de que la revisión sólo se aplica al elemento seleccionado que tiene autopostback establecido en true (onchange) una vez.
  2. Básicamente confiamos en jQuery para activar el evento de cambio para nosotros, pero para que IE lo haga, necesitamos desencadenar un evento de desenfoque de elemento cuando se produce onpropertychange.
1

clonar el control y añadir el clon inmediatamente después del previsto y asignar el evento, a continuación, quitar el control:

if ($.browser.msie && (parseInt($.browser.version, 10) == 8 || parseInt($.browser.version, 10) == 7)) { 
    var btn2 = $(btn).clone(); 
    $(btn).after(btn2); 
    $(btn).remove(); 
    $(btn2).bind("click", function() { 
     //your function here 
    }); 
}