javascript - multiple - Jquery: cambiar el evento al archivo de entrada en IE
on click jquery (15)
Ya miré por todas partes, y no puedo encontrar una solución: tengo un formulario para subir archivos, y debe iniciar el envío después de la selección del archivo.
En FF / Chrome va bien, y envía el formulario después de la selección de archivos, pero no puedo hacer esto en ie.
Ya lo intenté con click / propertychange pero no ocurre nada. Algún código que ya probé:
$("#attach").attr("onChange", "alert(''I changed'')");
$("#attach").live($.browser.msie? ''propertychange'': ''change'', function(e) { ... });
Alguna sugerencia a intentar?
Edit1: Creo que hay una información importante, este archivo de entrada, se crea sobre la marcha, debido a eso uso .live () para enlazar el evento
En el evento IE onchange funciona bien cuando se completa directamente en la etiqueta html. Me gusta:
<input type="file" onchange="uploader.upload()" />
Encontré esta solución en HTML hide file element (no use display: none, no funcionará en IE), prepare el evento onchange 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, la función de enlace se desenfoca, y para FF, CH bind función de cambio ():
$(iFile).blur(
function () {
...some code...
}
);
// FF, CH
$(iFile).change(
function () {
...some code...
}
);
Estaba teniendo el mismo problema con IE (incluido IE 9). La lógica de UI es:
- hacer clic en un elemento
div
activa el eventoclick
en unfile-input-element
para que el usuario haga clic en un diálogo de abrir archivo de activacióndiv
- vincular el controlador de eventos de
change
alfile-input-element
para garantizar que elform
se envíe cuando se cierre el cuadro de diálogo de abrir archivo
La aplicación (que se ejecuta dentro de un iframe) funciona como un amuleto 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 soltar la lógica # 1 "hacer clic en el elemento de activación del elemento div
" en el elemento de entrada de archivo "y dejar que el usuario haga clic en el file input element
del file input element
directamente, y luego funciona.
Por cierto, la razón por la que tenemos un elemento div
es que queremos ocultar los controles renderizados por el navegador porque tenemos todo en la imagen de fondo. Sin embargo, establecer la 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
fuera 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 su opacity
en 0. En IE 8 o menos que no admite opacity
, utilizamos 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)";
}
Este es probablemente un problema con una condición de carrera 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.
Resolví una situación similar haciendo lo siguiente dentro de mi controlador de cambios:
if (jQuery.browser.msie) { setTimeout(DoSomeUIChange, 0); } else { DoSomeUIChange(); }
El DoSomeUIChange se ejecuta después del código actual en la cola de eventos y así elimina la condición de carrera.
Esto es muy tarde, pero estaba teniendo el mismo problema, y lo resolví usando una <label>
con una pequeña solución para Firefox.
http://jsfiddle.net/djibouti33/uP7A9/
Los objetivos:
- Permitir al usuario cargar un archivo usando el control de entrada de archivo html estándar
- ocultar el control de entrada de archivo html estándar y aplicar un estilo propio
- después de que el usuario selecciona el archivo para cargar, envía automáticamente el formulario
Los navegadores:
- Firefox, Chrome, IE8 / 9, Safari
- IE7 no funcionó, pero podría ser que agregue ese navegador a la solución detallada en la parte inferior
La solución inicial:
- Oculte la entrada de archivo colocándolo fuera de pantalla. Importante no mostrar: ninguno ya que a algunos navegadores no les gustará esto.
- Agregue otro elemento con estilo a la página (enlace, botón).
- Preste atención a un clic en ese elemento y luego, mediante programación, envíe un clic a la entrada del archivo para activar el ''explorador de archivos'' nativo.
- Escuche el evento onchange de la entrada de archivo (se produce después de que un usuario elige su archivo)
- Envíe el formulario
El problema:
- IE: si programáticamente envía un clic a una entrada de archivo para activarlo (2), enviar el formulario (5) mediante programación enviará un error de seguridad
La solución alternativa:
- Lo mismo que arriba
- Aproveche las características de accesibilidad incorporadas en la etiqueta (al hacer clic en una etiqueta se activará su control asociado) al diseñar una etiqueta en lugar de un enlace / botón
- Escuche el evento onchange de la entrada del archivo
- Envíe el formulario
- Por algún motivo, los navegadores de Mozilla no activarán la entrada de un archivo haciendo clic en él.
- Para Mozilla, escuche el clic en la etiqueta y envíe un evento de clic a la entrada del archivo para activarlo.
¡Espero que esto ayude! Consulte el jsfiddle para obtener más información sobre html / js / css utilizado para que todo funcione.
Esto siempre me ha funcionado en IE6 ad IE7.
$(''#id-of-input-type-file'').change(function(){});
Formatealo así:
$("#attach").change(function() {
alert(''I Changed'');
});
Actualización: después de responder a otra pregunta anterior, nos dimos cuenta de que esto se había solucionado como parte de la reescritura de eventos de jQuery 1.4.2 , simplemente actualicémonos a la última versión para resolver el problema del evento de change
con <input type="file" />
en IE.
Mi solución:
setInterval(function()
{
if ($.browser.msie) $("input[type=file]").blur();
},500);
No es bonita, pero funciona. ;RE
Mira estos violines 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, probado.
Para IE Puede usar el evento "onfocus" para capturar 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. Puede verificar esto agregando 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.
Puedo confirmar, al menos, que solo funciona después de un evento de desenfoque, similar a una radio y una 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.
cojo.
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 las entradas de archivos ocurre después de la selección del archivo. En IE7, solo ocurre si activa el archivo de nuevo o en desenfoque.
Así es como terminé solucioná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, podrías / deberías filtrar la condición de hack a solo 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 Chrome está relacionado con el navegador (supongo que lo bloquea) O), entonces funciona tal cual.
Usé 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);
jQuery no parece reconocer el evento de cambio de propertychange
. Lo agregué al nodo DOM usando attachEvent()
IE.
var userChoseFile = function($input) {
// ...
}
var $input = $(/* your file input */);
$input[0].attachEvent(''onpropertychange'', function() {
userChoseFile($input);
});
$("#attach").attr("onChange", "alert(''I changed'')");
Funciona en IE, pero si desea emular el comportamiento "en vivo", debe agregar el atributo "onChange" a cada nuevo elemento cuando cree su.