Cuadro de diálogo Abrir archivo en JavaScript

109

Necesito una solución para mostrar el diálogo de archivo abierto en HTML mientras hago clic en un archivo div. El cuadro de diálogo para abrir archivo debe abrirse cuando divse hace clic en.

No quiero mostrar el cuadro del archivo de entrada como parte de una página HTML. Debe mostrarse en un cuadro de diálogo separado, que no forma parte de la página web.

Arca
fuente
4
¿Una alerta no es un diálogo de archivo? - ¿Puede aclarar lo que está preguntando?
LiamB
3
Creo que está diciendo que quiere la ventana emergente estándar de "archivo abierto"
Valentin Rocher
1
Necesito abrir el cuadro de diálogo de archivo cuando se hace clic en un div. debe ser como una alerta que no es parte de la página web
ARK

Respuestas:

52

Aqui hay uno lindo

Demostración de Fine Uploader

Es un <input type='file' />control en sí mismo. Pero se coloca un div sobre eso y se aplican estilos CSS para obtener esa sensación. La opacidad del control de archivo se establece en 0 para que parezca que la ventana de diálogo se abre al hacer clic en el div.

rahul
fuente
1
¿Hay alguna manera de controlar los archivos mostrados por javascript ... digamos que quería abrir el cuadro de diálogo del archivo y solo quería la extensión del archivo con .pdf para mostrar?
Ajax3.14
1
@ Ajax3.14 los nuevos navegadores tienen el objeto FileReader, los navegadores antiguos deben usar el valor y buscar la extensión del archivo.
Vicary
2
@ Ajax3.14 No es necesario utilizar FileReader o analizar extensiones. Muchos navegadores admiten el atributo de aceptación en las entradas de archivos. Esto le permite limitar los tipos de archivos que se muestran en el cuadro de diálogo del navegador de archivos. Fine Uploader proporciona acceso a esta funcionalidad a través de la propiedad acceptFiles de la opción de validación. Consulte la sección de validación de la documentación de opciones para obtener más detalles. Tenga en cuenta que el atributo de aceptación no es compatible con IE9 o versiones anteriores.
Ray Nicholus
1
como es que esto es bueno esto es una buena práctica en absoluto? no debería ser algo como esto: stackoverflow.com/a/18659941/915865 ?
Kat Lim Ruiz
1
@KatLimRuiz No, la respuesta a la que vinculó no es una buena solución. Esto hará que IE arroje un error si termina enviando el formulario asociado también mediante programación.
Ray Nicholus
77

    $("#logo").css('opacity','0');
    
    $("#select_logo").click(function(e){
       e.preventDefault();
       $("#logo").trigger('click');
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" id="select_logo">Select Logo</a> <input type="file" id="logo">

para IE agregue esto:

$("#logo").css('filter','alpha(opacity = 0');
Somwang Souksavatd
fuente
3
¿Por qué devuelve falso en el controlador de clics #select_logo?
Sethish
4
No produciría un error 404, solo intentaría navegar a la página actual, con el # agregado al final. Lo que haría que la página saltara a la parte superior. Así que es bueno estar allí, solo por una razón diferente :)
manavo
3
Aunque no lo he probado lo suficiente, "visibilidad: oculta"; parece más compatible. Además, a pesar de la opacidad: 0, se activará un evento de clic si el elemento "invisible" hizo clic, mientras que la visibilidad: oculta no lo hará.
Aron
MDN indica que document.getElementById("logo").click()es suficiente. También muestran otra forma de "Arrastrar y soltar". developer.mozilla.org/en-US/docs/Web/API/File/…
Eric
2
Debería convertir esto a Javascript normal, JQuery no es lógico para usar en un proyecto tan pequeño ^ _ ^
Mister SirCode
57

No sé por qué nadie ha señalado esto, pero aquí hay una forma de hacerlo sin Javascript y también es compatible con cualquier navegador.


EDITAR: En Safari, inputse desactiva cuando se oculta con display: none. Un mejor enfoque sería utilizar position: fixed; top: -100em.


<label>
  Open file dialog
  <input type="file" style="position: fixed; top: -100em">
</label>

Si lo prefiere, puede seguir el "camino correcto" utilizando foren el que labelapunta a idla entrada de esta manera:

<label for="inputId">file dialog</label>
<input id="inputId" type="file" style="position: fixed; top: -100em">
JP de la Torre
fuente
4
esto funciona de maravilla, sin embargo, aquí hay algunas recomendaciones: 1. la <input>etiqueta debe tener nameatributo; 2. si forse especifica un atributo, <input>la etiqueta de archivo requerirá un id.
Raptor
5
Simplicity is the ultimate sophistication
ncubica
2
¡Excelente! Funciona como un encanto incluso con una imagen de fondo o haciendo que la etiqueta reciba un clic activado por JavaScript. ¡Gracias!
Leo Nomdedeu
2
Por cierto, alguien señaló una captura con esta solución, en Safari, las entradas ocultas display: noneestán desactivadas. La solución alternativa es utilizar un enfoque diferente para ocultar la entrada. Actualizaré la respuesta para reflejar eso.
JP de la Torre
1
@JPdelaTorre Sería mucho mejor si usaras opacity: 0 en lugar de ocultar la entrada.
Adrian
39

En realidad, no necesitas todas esas cosas con opacidad, visibilidad, <input>estilo, etc. Solo echa un vistazo:

<a href="#">Just click me.</a>
<script type="text/javascript">
    $("a").click(function() {
        // creating input on-the-fly
        var input = $(document.createElement("input"));
        input.attr("type", "file");
        // add onchange handler if you wish to get the file :)
        input.trigger("click"); // opening dialog
        return false; // avoiding navigation
    });
</script>

Demostración en jsFiddle . Probado en Chrome 30.0 y Firefox 24.0. Sin embargo, no funcionó en Opera 12.16.

Tigran Saluev
fuente
3
Esta debería ser la respuesta correcta. Para una implementación pura de Javascript, no es necesario modificar ningún código HTML.
Zhang Buzz
21
Pregunta tonta, pero ¿cómo obtendría el archivo elegido después?
Jay Wick
2
Esta es una solución peligrosa que puede resultar en problemas inesperados. Por ejemplo, algunos navegadores (como IE) pueden evitar el envío de un formulario mediante programación si la entrada del archivo también se abre mediante programación. La mejor manera de resolver este problema es con CSS, no con JavaScript.
Ray Nicholus
3
@Charleston Desafortunadamente, no funciona en algunos navegadores. Sin embargo, deberían hacerlo funcionar :)
Tigran Saluev
3
A partir de 2020, esta solución parece la mejor. Lo probé en BrowserStack en Edge, Safari, Opera, Firefox y Chrome. Funciona en todos ellos.
V.Rubinetti
14

Esto es lo que mejor funcionó para mí (probado en IE8, FF, Chrome, Safari).

#file-input {
  cursor: pointer;
  outline: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  overflow: hidden;
  filter: alpha(opacity=0); /* IE < 9 */
  opacity: 0;
}
.input-label {
  cursor: pointer;
  position: relative;
  display: inline-block;
}
<label for="file-input" class="input-label">
  Click Me <!-- Replace with whatever text or icon you wish to use -->
  <input type="file" id="file-input">
</label>

Explicación: coloqué la entrada del archivo directamente encima del elemento en el que se va a hacer clic, por lo que cualquier clic aterrizaría en él o en su etiqueta (que abre el cuadro de diálogo de carga como si hiciera clic en la etiqueta). Tuve algunos problemas con la parte del botón de la entrada predeterminada que sobresalía del lado de la etiqueta, por lo que overflow: hiddenla entrada y display: inline-blockla etiqueta eran necesarias.

Chris
fuente
1
Maximice la entrada y establezca la opacidad en cero. ¡Eso funciona genial!
Kinorsi
13

¿Qué pasa si JavaScript está desactivado en la máquina del cliente? Utilice la siguiente solución para todos los escenarios. Ni siquiera necesitas javascript / jQuery. :

HTML

<label for="fileInput"><img src="File_upload_Img"><label>
<input type="file" id="fileInput"></label>

CSS

#fileInput{opacity:0}  
body{
    background:cadetblue;
}

Explicación: for="Your input Id". Activa el evento de clic de forma predeterminada por HTML. Entonces, de forma predeterminada, activa el evento de clic, sin necesidad de jQuery / javascript. Si simplemente se hace con HTML, ¿por qué usar jQuery / jScript? Y no se puede saber si el cliente desactivó JS. Su característica debería funcionar aunque JS esté desactivado.

Trabajando jsFiddle (no necesitas JS, jquery)

Pratik
fuente
3
¿Por qué el fondo?
Solomon Ucko
12

Primero agregue las etiquetas de la cabeza :

<script>
   function showDialog(openFileDialog) {
       document.getElementById(openFileDialog).click();
   }
   function fileName(openFileDialog) {
       return document.getElementById(openFileDialog).value;
   }
   function hasFile(openFileDialog) {
       return document.getElementById(openFileDialog).value != "";
   }
   function fileNameWithoutFakePath(openFileDialog) {
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(fileName.lastIndexOf('\\') + 1);
   }
   function fakePathWithoutFileName(openFileDialog) {
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(0, fileName.lastIndexOf('\\'));
   }
</script>

si ya tienes etiquetas de script , simplemente agregue estas funciones arriba.

En sus etiquetas de cuerpo o formulario agregando:

<input type="file" style="display:none" id="yourDesiredOrFavoriteNameForTheNewOpenFileDialogInstance"/>

No importa en qué lugar de su html, es como si hubiera creado una nueva instancia del tipo OpenFileDialog class como variable global , cuyo nombre es el id del elemento, sin importar en qué lugar de su código o xaml, pero en su script o código no puedes escribir su nombre y luego leer una propiedad o llamar a una función, porque hay funciones globales que hacen aquellas que no están definidas en el elemento input type = "file". Solo tiene que dar a estas funciones la identificación del tipo de entrada oculta = "archivo", que es el nombre de la instancia de OpenFileDialog como cadena.

Para facilitar su vida al crear instancias de diálogos de archivos abiertos en su html, puede crear una función que lo haga:

function createAndAddNewOpenFileDialog(name) {
     document.getElementById("yourBodyOrFormId").innerHtml += "<input type='file' style='display:none' id='" + name + "'/>"
}

y si desea eliminar el diálogo de archivo abierto, puede crear y usar la siguiente función:

function removeOpenFileDialog(name) {
    var html = document.getElementById("yourBodyOrFormId").innerHtml;
    html = html.replace("<input type='file' style='display:none' id='" + name + "'/>", "");
    document.getElementById("yourBodyOrFormId").innerHtml = html;
}

pero antes de eliminar el diálogo de archivo abierto, asegúrese de que exista creando y usando la siguiente función:

function doesOpenFileDialogExist(name) {
    return document.getElementById("yourBodyOrFormId").innerHtml.indexOf("<input type='file' style='display:none' id='" + name + "'/>") != -1
}

y si no desea crear y agregar los diálogos de archivos abiertos en el cuerpo o las etiquetas de formulario en el html, porque esto está agregando el tipo de entrada oculto = "file" s, entonces puede hacerlo en el script usando la función de creación anterior :

function yourBodyOrFormId_onload() {
    createAndAddNewOpenFileDialog("openFileDialog1");
    createAndAddNewOpenFileDialog("openFileDialog2");
    createAndAddNewOpenFileDialog("openFileDialog3");
    createAndAddNewOpenFileDialog("File Upload");
    createAndAddNewOpenFileDialog("Image Upload");
    createAndAddNewOpenFileDialog("bla");
    //etc and rest of your code
}

Asegúrese de que cerca de sus etiquetas de cuerpo o formulario, haya agregado:

onload="yourBodyOrFormId_onload()"

No tiene que hacer esta línea de arriba, si ya lo hizo.

SUGERENCIA: puede agregar a su proyecto o sitio web un nuevo archivo JScript, si aún no lo ha hecho, y en este archivo puede colocar todas las funciones de diálogo de archivo abierto fuera de las etiquetas de script y la página de formulario web o html, y usar en su página de formulario html o web desde este archivo JScript, pero no olvide antes vincular la página de formulario html o web al archivo JScript, por supuesto. Puede hacerlo simplemente arrastrando el archivo JScript a su página html en el encabezadoetiquetas. Si su página es un formulario web y no un simple html, y no tiene etiquetas de encabezado, colóquela en cualquier lugar para que funcione. No olvide definir la variable global en ese archivo JScript, cuyo valor será su cuerpo o id de formulario como cadena. Después de vincular el archivo JScript a su html o página de formulario web, puede cargar el evento de su cuerpo de formulario, establecer el valor de esa variable en su cuerpo o id de formulario. Luego, en el archivo JScript, ya no tienes que darle al documento la identificación del cuerpo o la forma de una página, solo dale el valor de esa variable. Puede llamar a esa variable bodyId o formId o bodyOrFormId o cualquier otro nombre que desee.

¡Buena suerte!


fuente
1
Es mejor no modificar directamente el innerHTML.
Solomon Ucko
9

La forma más sencilla:

#file-input {
  display: none;
}
<label for="file-input">
  <div>Click this div and select a file</div>
</label>
<input type="file" id="file-input"/>

Lo que es importante, el uso de display: noneasegura que ningún lugar será ocupado por la entrada del archivo oculto (lo que sucede al usar opacity: 0).

Karol Selak
fuente
3

AFAIK, todavía necesitas un <input type="file">elemento, entonces puedes usar algunas de las cosas de quirksmode para darle estilo

Dan F
fuente
2

Lo único que no <input type="file">ocurre es incrustar una película flash transparente sobre el div. A continuación, puede utilizar un evento de clic generado por el usuario (que cumpla con las nuevas reglas de seguridad de Flash 10) para activar una llamada a FileReference.browse de flash .

Ofrece una dependencia adicional sobre el modo quirksmode, pero a cambio obtienes muchos más eventos (como eventos de progreso integrados).

Martijn Laarman
fuente
-1

Puede usar

$('<input type="file" />').click()
Hamed Zakery Miab
fuente
en mi caso, esto provoca una redirección automática a la misma página donde ocurrió el evento de clic original, haciendo que toda la página se recargue y pierda todos los datos ingresados ​​previamente en la página.
Muntasir