Entrada de archivo de desencadenador jQuery

163

Estoy tratando de activar un cuadro de carga (botón de exploración) usando jQuery.
El método que he probado ahora es:

$('#fileinput').trigger('click');   

Pero no parece funcionar. Por favor ayuda. Gracias.

Alec Smart
fuente
Puedes probar algo como esto en su lugar.
Kirtan
19
¿No hay forma de hacer esto? Que deprimente.
Marcus Downing el
De hecho, deprimente, y se activa por 'clic', ¿en serio? Prefiero Flash / AS3, con su API ajustada y su fuerte modelo de seguridad que solo permite que se llame a FileReference.browse desde un controlador de eventos de entrada iniciado por el usuario. Además, la entrada del archivo HTML es fea y no tiene estilo (es solo una etiqueta de entrada, tanto para la separación del contenido y el estilo), por lo que debe crear un nuevo botón 'buscar', que también se activa mediante un evento de clic ... que debe reenviar a la entrada del archivo como un clic ... que puede conducir a una recursión infinita dependiendo de la ubicación del elemento y la especificidad de la delegación de eventos.
Triynko
Desafortunadamente, el uso de Flash se está volviendo cada vez menos viable, debido a sus constantes problemas de seguridad y al aumento de los bloqueadores de contenido.
Tim

Respuestas:

195

Esto se debe a una restricción de seguridad.

Descubrí que la restricción de seguridad es solo cuando <input type="file"/>se establece en display:none;o es visbilty:hidden.

Así que traté de colocarla fuera de la vista mediante el establecimiento position:absolutey top:-100px;y listo funciona.

ver http://jsfiddle.net/DSARd/1/

llámalo un hack.

Espero que eso te funcione.

adardesign
fuente
44
no funciona en ff 3.6. funciona en cromo e incluso en ie 8 aunque :)
AyKarsi
44
¿Hay alguna documentación en msdn sobre la restricción de seguridad?
eomeroff
2
Funciona genial. En cualquier caso, creo que es más seguro establecer a left: -100px;. Nunca se sabe cuánto tiempo podría ser una página
Alter Lagos
+1 Esta es la respuesta real (y una buena solución). ¿Alguien tendría un enlace a la documentación donde esto se establece explícitamente?
kontur
9
También puede establecer la opacidad a 0
Stuart
109

esto funcionó para mí:

JS:

$('#fileinput').trigger('click'); 

HTML:

<div class="hiddenfile">
  <input name="upload" type="file" id="fileinput"/>
</div>

CSS:

.hiddenfile {
 width: 0px;
 height: 0px;
 overflow: hidden;
}

>>> Otro que funciona Cross-Browser: <<<

La idea es que superponga un enorme botón invisible "Examinar" sobre su botón personalizado. Entonces, cuando el usuario hace clic en su botón personalizado, en realidad está haciendo clic en el botón "Examinar" del campo de entrada nativo.

JS Fiddle: http://jsfiddle.net/5Rh7b/

HTML:

<div id="mybutton">
  <input type="file" id="myfile" name="upload"/>
  Click Me!
</div>

CSS:

div#mybutton {

  /* IMPORTANT STUFF */
  overflow: hidden;
  position: relative;   

  /* SOME STYLING */
  width:  50px;
  height: 28px;
  border: 1px solid green;
  font-weight: bold
  background: red;
}

div#mybutton:hover {
  background: green;
}

input#myfile {
  height: 30px;
  cursor: pointer;
  position: absolute;
  top: 0px;
  right: 0px;
  font-size: 100px;
  z-index: 2;

  opacity: 0.0; /* Standard: FF gt 1.5, Opera, Safari */
  filter: alpha(opacity=0); /* IE lt 8 */
  -ms-filter: "alpha(opacity=0)"; /* IE 8 */
  -khtml-opacity: 0.0; /* Safari 1.x */
  -moz-opacity: 0.0; /* FF lt 1.5, Netscape */
}

JavaScript:

$(document).ready(function() {
    $('#myfile').change(function(evt) {
        alert($(this).val());
    });
});
trineo
fuente
Hay un defecto, si hace que el botón sea más ancho, entonces en IE9 / 10 el botón de carga invisible está compuesto por el botón derecho y un campo de texto izquierdo. En esto tienes que hacer doble clic. En este caso, intente configurar el tamaño de fuente incluso más grande que 100px;
yunzen
Esto funciona incluso en Chrome 53. Sin embargo, el heightse sugiere que el cambio aheight: 100%
Raptor
El segundo incluso funciona en Safari en iOS. ¡Muy agradable!
Jannis
71

Puede usar el elemento LABEL ex.

<div>
    <label for="browse">Click Me</label>
    <input type="file" id="browse" name="browse" style="display: none">//
</div>

Esto activará el archivo de entrada

Jhon Rey
fuente
55
¿Por qué no es esta la respuesta aceptada? Es la forma más simple que no requiere JavaScript funky.
tomitrescak
@tomitrescak el OP no está esperando obtener la mejor respuesta.
Mahi
9
Tenga en cuenta que la respuesta se publicó 7 años después de que se envió la pregunta.
1
La mejor respuesta en 2018 también.
masoomyf
1
La mejor respuesta para 2019 también;)
guillaumepotier
17

Lo tengo funcionando (= probado) en IE8 +, FF reciente y Chrome:

$('#uploadInput').focus().trigger('click');

La clave es enfocar antes de disparar el clic (de lo contrario, Chrome lo ignora).

Nota: NECESITA que su entrada se muestre y sea visible (como en, no display:noney no visibility:hidden). Sugiero (como muchos otros lo han hecho antes) posicionar absolutamente la entrada y lanzarla fuera de la pantalla.

#uploadInput {
    position: absolute;
    left: -9999px;
}
El poderoso pato de goma
fuente
1
+1 por eso. También noté que puede ocultar el elemento circundante pero no el botón de entrada del archivo, luego mostrar el elemento circundante, enfocar el botón, activarlo y luego ocultar el botón.
Stevo
10

Mira mi violín.

http://jsfiddle.net/mohany2712/vaw8k/

.uploadFile {
  visibility: hidden;
}

#uploadIcon {
  cursor: pointer;
}
<body>
  <div class="uploadBox">
    <label for="uploadFile" id="uploadIcon">
      <img src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Icon_-_upload_photo_2.svg/512px-Icon_-_upload_photo_2.svg.png"  width="20px" height="20px"/>
    </label>
    <input type="file" value="upload" id="uploadFile" class="uploadFile" />
  </div>
</body>

Mohan
fuente
9

adardesign lo logró con respecto al elemento de entrada del archivo que se ignora cuando está oculto. También noté que muchas personas cambiaban el tamaño del elemento a 0, o lo sacaban de los límites con ajustes de posicionamiento y desbordamiento. Estas son todas grandes ideas.
Una forma alternativa que también parece funcionar perfectamente bien es simplemente establecer la opacidad en 0 . Entonces siempre puede establecer la posición para evitar que compense otros elementos como lo hace hide. Simplemente parece un poco innecesario cambiar un elemento de casi 10K píxeles en cualquier dirección.

Aquí hay un pequeño ejemplo para aquellos que quieren uno:

input[type='file']{
    position:absolute;
    opacity:0;
    /* For IE8 "Keep the IE opacity settings in this order for max compatibility" */
    -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
    /* For IE5 - 7 */
    filter: alpha(opacity=0);
}
eyegropram
fuente
7

Solo por curiosidad, puede hacer algo como desee creando dinámicamente un formulario de carga y un archivo de entrada, sin agregarlo al árbol DOM:

$('.your-button').on('click', function() {
    var uploadForm = document.createElement('form');
    var fileInput = uploadForm.appendChild(document.createElement('input'));

    fileInput.type = 'file';
    fileInput.name = 'images';
    fileInput.multiple = true;

    fileInput.click();
});

No es necesario agregar el uploadForm al DOM.

jairhumberto
fuente
1
¡GRACIAS! ¡He estado buscando esto por 20 minutos!
Labo
5

Código correcto:

<style>
    .upload input[type='file']{
        position: absolute;
        float: left;
        opacity: 0; /* For IE8 "Keep the IE opacity settings in this order for max compatibility" */
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /* For IE5 - 7 */
        filter: alpha(opacity=0);
        width: 100px; height: 30px; z-index: 51
    }
    .upload input[type='button']{
        width: 100px;
        height: 30px;
        z-index: 50;
    }
    .upload input[type='submit']{
        display: none;
    }
    .upload{
        width: 100px; height: 30px
    }
</style>
<div class="upload">
    <input type='file' ID="flArquivo" onchange="upload();" />
    <input type="button" value="Selecionar" onchange="open();" />
    <input type='submit' ID="btnEnviarImagem"  />
</div>

<script type="text/javascript">
    function open() {
        $('#flArquivo').click();
    }
    function upload() {
        $('#btnEnviarImagem').click();
    }
</script>
E9 Sistemas
fuente
4

Eso es a propósito y por diseño. Es un problema de seguridad.

Chad Grant
fuente
4

En realidad, descubrí un método realmente fácil para esto, que es:

$('#fileinput').show().trigger('click').hide();   

De esta manera, el campo de entrada de su archivo puede mostrar la propiedad css en ninguno y aún así ganar el comercio :)

skywlkr
fuente
podría parpadear en la pantalla de la máquina más lenta. No es una solución óptima
Dmitry Efimenko
4

Es demasiado tarde para responder, pero creo que esta configuración mínima funciona mejor. También estoy buscando lo mismo.

  <div class="btn-file">
     <input type="file" class="hidden-input">
     Select your new picture
  </div>

// css

.btn-file {
  display: inline-block;
  padding: 8px 12px;
  cursor: pointer;
  background: #89f;
  color: #345;
  position: relative;
  overflow: hidden;
}

.btn-file input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  filter: alpha(opacity=0);
  opacity: 0;
  cursor: inherit;
  display: block;
}

jsbin

demostración de botones de entrada de archivos de arranque

Natwar Singh
fuente
nunca es tarde para responder;)
AGuyCalledGerald
Pocos años después, la mejor respuesta es IMO
DimmuR
4

Esta es una pregunta muy antigua, pero desafortunadamente este problema sigue siendo relevante y requiere una solución.

La solución (sorprendentemente simple) que se me ocurrió es "ocultar" el campo de entrada del archivo real y envolverlo con una etiqueta LABEL (puede basarse en Bootstrap y HTML5, para mejorar).

See here:Código de ejemplo aquí

De esta manera, el campo de entrada del archivo real es invisible y todo lo que ve es el "botón" personalizado que en realidad es un elemento LABEL modificado. Cuando hace clic en este elemento LABEL, aparece la ventana para seleccionar un archivo y el archivo que elija irá al campo de entrada del archivo real.

Además de eso, puede manipular el aspecto y el comportamiento que desee (por ejemplo: obtener el nombre del archivo seleccionado del archivo de entrada del archivo, después de seleccionarlo, y mostrarlo en algún lugar. El elemento LABEL no hace eso automáticamente, por supuesto, generalmente lo pongo dentro de LA LABEL, como su contenido de texto).

¡Pero cuidado! La manipulación de la apariencia y el comportamiento de esto se limita a todo lo que puedas imaginar y pensar. ;-) ;-)

TheCuBeMan
fuente
3

Me las arreglé con un simple $ (...). Clic (); con JQuery 1.6.1

Valentin Galea
fuente
1
Mmm, curioso cómo lo hiciste, en mi sitio web (www.iscriptdesign.com) haciendo un $ ('file: input'). Click () no hace nada, ni $ ('file: input'). Trigger (' hacer clic');
dr jerry
Aquí está el ejemplo completo: <input type = "file" id = "picBrowse" ... y luego $ ('# picBrowse'). Click ();
Valentin Galea
Probé en cr (no estoy seguro de qué versión) en mac os, aunque funciona en FF 4 en XP. ¡Gracias!
dr jerry
3

o simplemente

$(':input[type="file"]').show().click().hide();
Otvazhnii
fuente
2

Tuve problemas con la validación personalizada del lado del cliente durante el <input type="file"/>uso de un botón falso para activarlo y la solución de @Guillaume Bodi funcionó para mí (también con opacity: 0;Chrome)

$("#MyForm").on("click", "#fake-button", function () {
        $("#uploadInput").focus().trigger("click");
    });

y estilo CSS para la entrada de carga

#uploadInput {
opacity: 0.0; 
filter: alpha(opacity=0); /* IE lt 8 */
-ms-filter: "alpha(opacity=0)"; /* IE 8 */
-khtml-opacity: 0.0; /* Safari 1.x */
-moz-opacity: 0.0;
}
Amin K
fuente
1

Prueba esto, es un truco. la Posición: absoluta es para Chrome y el disparador ('cambio') es para IE.

var hiddenFile = $("<input type=\"file\" name=\"file\" id=\"file1\" style=\"position:absolute;left:-9999px\" />");
$('body').append(hiddenFile);

$('#aPhotoUpload').click(function () {
    hiddenFile.trigger('click');
    if ($.browser.msie)
        hiddenFile.trigger('change');
});

hiddenFile.change(function (e) {
    alert('TODO');
});
thinpiglin
fuente
Tenga en cuenta que $.browserestá en desuso en las versiones más recientes de jQuery
Kevin Beal
1

Mi problema era un poco diferente en iOS 7. Resulta que FastClick estaba causando problemas. Todo lo que tenía que hacer era agregar class="needsclick"a mi botón.

Dex
fuente
0

Esta es probablemente la mejor respuesta, teniendo en cuenta los problemas del navegador cruzado.

CSS:

#file {
  opacity: 0;
  width: 1px;
  height: 1px;
}

JS:

$(".file-upload").on('click',function(){
   $("[name='file']").click();
});

HTML:

<a class="file-upload">Upload</a>
<input type="file" name="file">
Eddsters
fuente
0

Creo que entiendo tu problema, porque tengo un similar. Para que la etiqueta <label>tenga el atributo, puede usar este atributo para vincular su entrada con type = "file". Pero si no desea activar esto usando esta etiqueta porque alguna regla de su diseño, puede hacer esto.

$(document).ready(function(){
  var reference = $(document).find("#main");
  reference.find(".js-btn-upload").attr({
     formenctype: 'multipart/form-data'
  });
  
  reference.find(".js-btn-upload").click(function(){
    reference.find("label").trigger("click");
  });
  
});
.hide{
  overflow: hidden;
  visibility: hidden;
  /*Style for hide the elements, don't put the element "out" of the screen*/
}

.btn{
  /*button style*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<div id="main">
<form enctype"multipart/formdata" id="form-id" class="hide" method="post" action="your-action">
  <label for="input-id" class="hide"></label>
  <input type="file" id="input-id" class="hide"/>
</form>

<button class="btn js-btn-upload">click me</button>
</div>

Por supuesto, adaptará esto para su propio propósito y diseño, ¡pero esa es la forma más fácil que sé para que funcione!

Leonardo Lindroth
fuente
-1

Basado en la respuesta de Guillaume Bodi, hice esto:

$('.fileinputbar-button').on('click', function() {
    $('article.project_files > header, article.upload').show();
    $('article.project_files > header, article.upload header').addClass('active');
    $('.file_content, article.upload .content').show();
    $('.fileinput-button input').focus().click();
    $('.fileinput-button').hide();
});

lo que significa que está oculto para comenzar y luego se muestra para el desencadenante, luego se oculta nuevamente de inmediato.

Stevo
fuente