2010-03-05 28 views
35

Ya busqué por todas partes, y no encuentro una solución: tengo un formulario para cargar archivos, y debe iniciar el envío después de la selección del archivo.Jquery: cambiar el evento al archivo de entrada en IE

En FF/Chrome va bien, y envía el formulario después de la selección del archivo, pero no puedo hacer esto en ie.

Ya lo intenté con clic/cambio de propiedad pero no ocurre nada. Parte del código Ya he probado:

$("#attach").attr("onChange", "alert('I changed')");

$("#attach").live($.browser.msie? 'propertychange': 'change', function(e) { ... });

Cualquier sugerencias a intentar?

Edit1: Creo que hay una información importante, este archivo de entrada, se crea sobre la marcha, a causa de ello utilizo .live() para vincular el evento

+2

Para elementos que ya existen, IE's attachEvent() funciona: $ ('# attach') [0] .attachEvent ('onpropertychange', function() {...}) –

+0

Tuve el mismo problema, este hilo solucionado mi problema http://stackoverflow.com/questions/4150256/jquery-change-event-on-file-input-element-does-not-fire-if-the-file-selection –

Respuesta

10

Formato así:

$("#attach").change(function() { 
    alert('I Changed'); 
}); 

actualización: Después de responder en este another question anterior, nos dimos cuenta de esto se fijará en el marco de la jQuery 1.4.2 event re-write, simplemente actualizar a la última versión para resolver el problema change evento con <input type="file" /> en IE.

+0

No, sólo se en Firefox/Chrome, IE8/IE7. Creo que hay una información importante, este archivo de entrada, se crea sobre la marcha, por eso uso .live() para enlazar el evento. Gracias – cmedeiros

+0

@cmedeiros - ¿Cuántos creas sobre la marcha? –

+0

Solo uno, este es el código: 'var e = $ ("

"+$("#compose").html()+"
"); $ (". Middle-center"). Append (e); ' El archivo de entrada está dentro de $ ("# compose"). Html(), pero traté de ponerlo en un archivo html simple y tampoco funcionó – cmedeiros

2

Esto siempre me ha funcionado en IE6 ad IE7.

$('#id-of-input-type-file').change(function(){}); 
+2

Funciona solo cuando hago clic en cualquier lugar de la pantalla. – cmedeiros

0

Puedo confirmar, al menos, que solo funciona después de un evento de desenfoque, similar a una radio y casilla de verificación en IE. Probablemente tenga que agregar algún tipo de elemento visual para que el usuario haga clic y me diga cuándo han elegido su archivo.

lame.

1

Esto es probablemente un problem with a race condition con campos de entrada en IE. Al usar setTimeout, la función que se ejecuta registrará que se produjo un cambio. Cuando el código de UI se ejecuta en el evento onChangeEvent, ese evento no se ha activado aún, como parece a IE.

he resuelto una situación similar de la siguiente manera dentro de mi manejador de cambio:

if (jQuery.browser.msie) { setTimeout(DoSomeUIChange, 0); } else { DoSomeUIChange(); } 

El DoSomeUIChange se ejecuta después de que el código actual en la cola de eventos y así elimina la condición de carrera.

+1

Tiempos de espera e intervalos __do not__ crear hilos.Todo sigue ejecutándose en serie en una única cola de eventos, sin importar cuántos temporizadores crees o cuántos intervalos establezcas o cuántos eventos tengas que procesar a la vez. – zneak

+0

Gracias zneak. Actualicé la publicación para reflejar esto. – spig

40

Sé que esto es varios meses tarde, pero acabo de encontrar exactamente el mismo comportamiento en IE7; en todos los demás navegadores, el evento de cambio para entradas de archivos ocurre después de la selección del archivo. En IE7, solo ocurre si activa nuevamente el archivo, o si está borroso.

Así es como acabé fijándolo:

var $input = $('#your-file-input-element'); 

var someFunction = function() 
{ 
    // what you actually want to do 
}; 

if ($.browser.msie) 
{ 
    // IE suspends timeouts until after the file dialog closes 
    $input.click(function(event) 
    { 
     setTimeout(function() 
     { 
      if($input.val().length > 0) { 
       someFunction(); 
      } 
     }, 0); 
    }); 
} 
else 
{ 
    // All other browsers behave 
    $input.change(someFunction); 
} 

Técnicamente se podría/debería filtrar la condición truco para simplemente IE7, ya que IE8 se comporta correctamente en el evento de cambio, pero también tiene el mismo comportamiento que IE7 al suspender los tiempos de espera mientras que el cromo relacionado con el navegador está visible (supongo que lo considera bloqueando E/S), por lo que funciona tal como está.

+0

Gracias por esto. Todavía no hay una solución dentro del núcleo de jQuery. –

+0

esto funcionó para mí perfectamente, pero quiero entender lo que hizo el settime? y cómo resolvió el problema? no puedo entenderlo –

+0

Hola Amr: No he notado tu comentario hasta ahora. Funciona porque IE parece considerar un diálogo como el diálogo de archivo esencialmente para bloquear E/S: toda ejecución de javascript se detiene mientras está abierta. Esto significa que si esencialmente deja que el controlador de clic se complete para que IE abra el cuadro de diálogo y luego llame inmediatamente a su devolución de llamada (por ejemplo, estableciendo un tiempo de espera de cero), entonces debería suceder tan pronto como se cierre el cuadro de diálogo. –

1

En el evento IE onchange funciona bien cuando se completa en la etiqueta html directamente.Me gusta:

<input type="file" onchange="uploader.upload()" /> 
1

Para IE Puede utilizar el evento "onfocus" para ver el cambio de archivo de carga. Una vez que se cierra el cuadro de diálogo de búsqueda de archivos, se desencadena el evento onfocus. Esto se puede comprobar mediante la adición de esta línea a su página:

<input type="file" onfocus="javascript:alert('test');" />

Una vez que se cierra el diálogo se muestra el mensaje de alerta.

Esta solución es solo para IE, no para FF o Chrome.

+0

¿Quiere decir 'onfocus =" alert ('test'); "'? – Raptor

0
$("#attach").attr("onChange", "alert('I changed')"); 

Funciona en IE, pero si quieres emular el comportamiento "en vivo", se debe añadir el atributo "onchange" para cada nuevo elemento al crear su.

1

Mi solución:

setInterval(function() 
{ 
    if ($.browser.msie) $("input[type=file]").blur(); 
},500); 

No es bonita, pero funciona. ; D

+0

Desafortunadamente, esta solución setInterval() aún se necesita con jquery1-6.4 e IE7. – guettli

3

He utilizado la siguiente solución. Traté de hacerlo tan autónomo como sea posible.

(function($) { 
    if ($.browser.msie == false) 
     return; 

    $('input[type=file]').live('click', function(e) { 
     var self = this; 
     var blur = function() { 
      $(self).blur(); 
     } 
     setTimeout(blur, 0); 
    }); 

})(jQuery); 
2

Estaba teniendo el mismo problema con IE (incluido IE 9). La lógica de la interfaz de usuario es:

  1. clic en un elemento de div activa el evento click en un file-input-element de manera que el usuario haga clic en un archivo de div gatillo abierto de diálogo
  2. se unen al controlador de change evento al file-input-element para garantizar la form es enviado cuando el archivo abre el cuadro de diálogo cerrado

La aplicación (que se ejecuta dentro de un iframe) funciona como un encanto en Chrome y FF. Pero pronto descubrí que no funciona en IE como cuando el usuario seleccionó un archivo y cerró el diálogo que el formulario no envió.

La solución final es dejar caer la lógica # 1 "haga clic en div elemento desencadenante click evento el elemento de entrada de archivo" y permitir al usuario a hacer clic en el file input element directamente, y entonces funciona.

Por cierto, el motivo por el que tenemos un elemento div es que queremos ocultar los controles representados en el navegador porque tenemos todo en la imagen de fondo. Sin embargo, establecer display en none hace que el control no pueda responder a un evento de interacción del usuario. Así que movemos el file-input-element hacia afuera del puerto de vista y usamos un elemento div para reemplazarlo. Como esto no funciona en IE, terminamos retrocediendo el file-input-element y configuramos opacity en 0.En IE 8 o menos que no soporta opacity, usamos el filtro para hacerlo transparente:

#browse { 
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); 
    filter: alpha(opacity=0); 
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; 
} 
2

encontré esta solución En HTML elemento de archivo de ocultar (no utilice display: none, no va a funcionar en IE), preparar onchange caso de IE:

<div style="width: 0px; height: 0px; overflow: hidden;"> 
    <input id="ifile_template" type="file" onchange="this.focus(); this.blur();"/> 
</div> 

en JavaScript para IE función se unen a la falta de definición, y para FF, CH cambio de función bind():

$(iFile).blur(
    function() { 
    ...some code... 
    } 
); 

// FF, CH 
$(iFile).change(
    function() { 
    ...some code... 
    } 
); 
+0

¡Esta es solo una solución, realmente funciona! Probé muchas otras respuestas aquí, también todo lo de esto - http://stackoverflow.com/questions/16201278/jquerys-form-submit-not-firing-for-ie-only-mvc3-app, pero nada está funcionando, excepto ¡éste! ¡Muchas gracias! – Legionar

0

jQuery no parece reconocer el evento propertychange. Lo agregué al nodo DOM usando el IE attachEvent().

var userChoseFile = function($input) { 
    // ... 
} 

var $input = $(/* your file input */); 
$input[0].attachEvent('onpropertychange', function() { 
    userChoseFile($input); 
}); 
11

Esto es muy tarde, pero yo estaba teniendo el mismo problema, y ​​lo resolvió mediante el uso de una etiqueta de estilo <label> con una ligera solución para Firefox.

http://jsfiddle.net/djibouti33/uP7A9/

Los Objetivos:

  1. permite al usuario cargar un archivo mediante el control de entrada de archivo HTML estándar
  2. ocultar el control de entrada de archivo HTML estándar y aplicar estilo propio
  3. después el usuario selecciona el archivo para cargar, envía automáticamente el formulario

Los Navegadores:

  • Firefox, Chrome, Internet Explorer 8/9, Safari
  • IE7 no funcionó, pero podría si se agrega que el navegador a la solución se detalla en la parte inferior

la solución inicial:

  1. ocultar la entrada de archivo de posicionándolo fuera de la pantalla. Importante no mostrar: ninguno ya que a algunos navegadores no les gustará esto.
  2. Agregue otro elemento de estilo a la página (enlace, botón).
  3. escuche por un clic en ese elemento, a continuación, enviar mediante programación un clic para el archivo de entrada para activar el 'explorador de archivos' nativo
  4. Escuchar para el evento onchange del archivo de entrada (se produce cuando un usuario elige su archivo)
  5. enviar el formulario

el problema:

  1. IE: si se envía mediante programación un clic a un archivo de entrada con el fin de activarlo (2), pr la presentación de ogrammatically la forma (5) lanzará un error de seguridad

La Solución Solución:

  1. Igual que el anterior
  2. Tome ventaja de las características de accesibilidad integradas en la etiqueta (click en una etiqueta activará su control asociado) al diseñar una etiqueta en lugar de un enlace/botón
  3. Escuchar el evento de cambio de entrada de archivo
  4. Envíe el formulario
  5. Por alguna razón, los navegadores Mozilla no activarán la entrada de un archivo haciendo clic en él.
  6. Para Mozilla, escuche el clic en la etiqueta y envíe un evento de clic a la entrada del archivo para activarlo.

Hope this helps! Consulte el jsfiddle para obtener más información sobre html/js/css utilizado para que todo funcione.

+2

Esta fue la única solución que pude obtener para trabajar en nuestra fantaseada "Haga clic en esta imagen para subir una nueva" que estamos construyendo. ¡Muchas gracias! –

+0

Solución muy inteligente pero simple. Gracias. Usado con IE8 y Primefaces 5. – Tony

0

vistazo a estas violín http://jsfiddle.net/uP7A9/531/

HTML:

<input type="file" name="PicturePath" id="fileUpload" accept=".png,.jpg,.jpeg,.gif,.tif" /> 

jQuery:

$("input[type=file]#fileUpload").on("change", function() { 
    alert('hi') 
}); 

funciona para todos los navegadores, a prueba.

+0

No funciona en IE si type = text – shaosh

Cuestiones relacionadas