68 votos

Arrastre y suelte los archivos para subir en Google Chrome/Chromium y Safari?

Arrastre y suelte los archivos para la carga se puede hacer en Firefox 3.6.

Una búsqueda de Google en html5 arrastrar y soltar el archivo de la carga de gmail da cosas como:

Todas estas guías de uso FileReader (o el Firefox 3.6 es obsoleto getAsBinary, que ningún otro navegador soporta, tampoco).

Sin embargo, recientemente, Google lanzó una actualización para Gmail que permite arrastrar y soltar archivos a subir en Cromo, así como Firefox y Chromium no tiene FileReader. Estoy usando la última Cromo todas las noches, y se puede arrastrar y soltar archivos, subirlos, mientras no apoyar FileReader.

He visto a alguien mencionar que arrastrar-soltar la carga puede ser posible por arrastrar a un <input type="file" />, pero que sólo puede admitir un archivo a la vez, mientras que Gmail uploader puede manejar múltiples archivos de ser arrastrado hacia él, así que claramente no es lo que están haciendo.

Así que la pregunta es, ¿cómo lo hacen? ¿Cómo se puede apoyar el Cromo para HTML5 cargando archivo? Además, puede prestar apoyo a Safari?

33voto

Zarel Puntos 1711

EDIT: Google Chrome soporta ahora FileReader a partir de la versión 7. Sin embargo, esta solución todavía es necesario para arrastrar-y-soltar la carga en Safari 5 (Safari 6 no se ha publicado todavía).

Una posibilidad es utilizar el método utilizado en SwellJS:

Uso <input type="file" multiple="multiple" /> así:

<form method="post" enctype="multipart/form-data" id="uploadform">
  <input type="file" name="dragupload[]" multiple="multiple"
  onchange="if (this.value) document.getElementById('uploadform').submit();" />
</form>

El elemento de entrada puede ser de estilo para tener opacity: 0 y se coloca (absolutamente) a través de un elemento que acepta las subidas. El formulario puede ser colocado dentro de un iframe "pseudo-Ajax", como el comportamiento. Y la carga de elemento puede ser una capa que oculta hasta que algo se arrastra sobre él.

Un iframe, se vería así:

<script>
<!--
  var entered = 0;
-->
</script>
<body ondragenter="entered++;document.getElementById('uploadelement').style.display='block'" ondragleave="entered--;if (!entered) document.getElementById('uploadelement').style.display='none'">
  <form method="post" enctype="multipart/form-data" id="uploadform">
    Things can be dragged and dropped here!
    <input type="file" id="uploadelement" name="dragupload[]" multiple="multiple" onchange="if (this.value) { document.getElementById('uploadform').submit(); }" style="display:none;position:absolute;top:0;left:0;right:0;bottom:0;opacity:0;" />
  </form>
</body>

Esto sólo debe hacerse cuando Safari o Chrome se detecta (ya que otros navegadores no admiten la función de arrastrar y soltar en <input type="file" /> elementos), y puede ser utilizado en combinación con el HTML5 drop evento para Firefox 3.6+.

No sé si este es el método de Gmail utiliza, pero ciertamente funciona tan bien.

13voto

Arnaud Leymet Puntos 2387

Usted puede estar interesado en algo más de tecnología y navegador compatible.

A mí me parece que Plupload lo hace bien, el apoyo a las siguientes características:

  • Chunking
  • Arrastrar/Soltar
  • PNG cambiar el tamaño de
  • JPEG Resize
  • Filtrado de tipo de
  • Corriente de carga
  • Multipart subir
  • Tamaño del archivo de restricción
  • De progreso de la carga

para la mayoría de las siguientes tecnologías:

  • Flash
  • Engranajes
  • HTML 5
  • Silverlight
  • BrowserPlus

Y sí, desde 2010.05.27, soporta arrastrar y soltar para la ejecución de HTML5 en Chrome beta.

10voto

Casey Chu Puntos 8804

Tengo algo de trabajo en Chrome después de mucho, mucho, mucho trabajo de detective. Esto sólo funciona en Chrome. En Safari, se congela. En Firefox, no me deja colocar el archivo. Es decir, se abre el archivo perdido en su lugar. Incluso en Chrome, el arrastrar y soltar sólo funciona una vez, por alguna razón, después de lo cual usted tiene que actualizar la página. (Una posible razón para esto es que algo está mal con los controladores de eventos.)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <script type="text/javascript">
            window.onload = function () {
                var div = document.getElementById('div');
                div.ondragenter = div.ondragover = function (e) {
                    e.preventDefault();
                    e.dataTransfer.dropEffect = 'copy';
                    return false;
                }
                div.ondrop = function (e) {
                    for (var i = 0; i < e.dataTransfer.files.length; i++) { // e.dataTransfer is a DataTransfer object (https://developer.mozilla.org/En/DragDrop/DataTransfer), e.dataTransfer.files is a FileList object (https://developer.mozilla.org/en/DOM/FileList)
                        var file = e.dataTransfer.files[i]; // file is a File object (https://developer.mozilla.org/en/DOM/File)

                        var xhr = new XMLHttpRequest;
                        xhr.open('post', 'handler.php', true);
                        xhr.onreadystatechange = function () {
                            if (this.readyState != 4)
                                return;
                            document.body.innerHTML += '<pre>' + this.responseText + '</pre>';
                        }
                        xhr.setRequestHeader('Content-Type', 'multipart/form-data');
                        xhr.setRequestHeader('X-File-Name', file.fileName);
                        xhr.setRequestHeader('X-File-Size', file.fileSize);
                        xhr.send(file); // For some reason sending the actual File object in Chrome works?
                    }

                    e.preventDefault();
                    return false;
                }
            }
        </script>
    </head>
    <body>
        <div id="div" style="width: 100%; height: 200px; border: 1px solid blue">Drop here</div>
    </body>
</html>

handler.php:

    // This is not a true file upload. Instead, it sends the raw data directly.
    echo htmlentities(file_get_contents('php://input'));

2voto

Ryan Seddon Puntos 96

Usted no necesita usar un iframe para hacer pseudo ajax cargar. Chrome y Safari, tanto de apoyo XHR2 carga con el progreso de los eventos, así que usted puede hacer que las barras de progreso, etc.

2voto

Martin Puntos 21

Para nuestra propia aplicación, hacemos de arrastrar y soltar para FireFox. Acudimos de nuevo a la tradicional iframe de carga para los demás. Con el fin de detectar que arrastrar y soltar es compatible, ejecutamos este código:

if (typeof(window.File) == 'object' && typeof(window.FileReader) == 'function' && typeof(window.FileList) == 'object') {
   // DnD is supported!
}

Espero que esto sea de ayuda para algunos.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X