javascript - extension - ¿Cargar archivos arrastrados y soltados en Google Chrome/Chromium y Safari?
google console chrome (9)
ADVERTENCIA: este es el código de compatibilidad para versiones muy antiguas de Safari y Chrome. Los navegadores modernos son compatibles con la API FileReader; aquí hay un tutorial: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
Este código ahora solo es útil si por alguna razón necesitas admitir Safari 5 y versiones anteriores, o Chrome 6 y versiones anteriores.
Una posibilidad es utilizar el método utilizado en SwellJS :
Utilice <input type="file" multiple="multiple" />
como tal:
<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 se puede diseñar para tener opacity: 0
y posicionado (absolutamente) sobre un elemento que acepta cargas. El formulario completo se puede colocar dentro de un iframe
para un comportamiento similar al "pseudo-Ajax". Y el elemento de carga puede ser una capa oculta hasta que se arrastra algo sobre ella.
Tal 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 solo debe hacerse cuando Safari o Chrome se detectan (ya que otros navegadores no admiten arrastrar y soltar en elementos <input type="file" />
), y se pueden usar en combinación con el evento drop
HTML5 para Firefox. 3.6+.
No puedo decir si este es el método que usa Gmail, pero ciertamente también funciona.
La carga del archivo de arrastrar y soltar se puede hacer en Firefox 3.6.
Una búsqueda en Google para cargar archivos html5 arrastrando y soltando archivos -gmail da cosas como:
- Native Drag + Drop carga del archivo en Firefox 3.6
- http://www.appelsiini.net/2009/10/html5-drag-and-drop-multiple-file-upload
- http://www.thecssninja.com/javascript/drag-and-drop-upload
Todas estas guías usan FileReader
(o el obsoleto getAsBinary
Firefox 3.6, que ningún otro navegador admite).
Sin embargo, Google lanzó recientemente una actualización para Gmail que permitió la carga de archivos de arrastrar y soltar tanto en Chromium como en Firefox, y Chromium no tiene FileReader
. Estoy usando el último Chromium todas las noches, y puede arrastrar y soltar archivos de carga, aunque no es compatible con FileReader
.
He visto a alguien mencionar que la carga con arrastrar y soltar puede ser arrastrada a un <input type="file" />
, pero eso solo puede soportar un archivo a la vez, mientras que el cargador de Gmail puede manejar varios archivos que se arrastran hacia él. , entonces claramente no es lo que están haciendo.
Entonces la pregunta es, ¿cómo lo hacen? ¿Cómo se admite Chromium para la carga de archivos HTML5? Además, ¿puedes apoyar a Safari?
El último archivo de soporte del navegador se carga bien. Podrías usar:
xhr = new XMLHttpRequest();
xhr.open(''POST'', targetPHP, true);
var formData = new FormData();
formData.append(''upload'',file);
xhr.send(formData);
No es necesario establecer un límite o una cabeza, así funciona bien. Probé este código en el cliente: firefox 6.02 y en Chrome 13. server: tomcat con "spring mvc"
Es posible que le interese algo más compatible con la tecnología y el navegador.
Me parece que Plupload hace bien, compatible con las siguientes características:
- Chunking
- Arrastrar y soltar
- PNG Cambiar tamaño
- Tamaño JPEG
- Tipo de filtrado
- Carga de la secuencia
- Carga de varias partes
- Restricción de tamaño de archivo
- Progreso de carga
para la mayoría de las siguientes tecnologías:
- Destello
- Engranajes
- HTML 5
- Silverlight
- BrowserPlus
Y sí, Plupload , es compatible con arrastrar / soltar para HTML5 que se ejecuta en Chrome beta.
Establezca atributos múltiples como:
input type = "file" name = "file1" multiple = "multiple" class = "DropHere"
y usa esta clase CSS DropHere:
.DropHere
{
height: 100px;
padding: 3px;
border: 2px dashed #555;
border-radius: 5px;
cursor: default;
background-image:url("data:image/svg+xml;utf8, <svg xmlns=''http://www.w3.org/2000/svg'' version=''1.1'' height=''100px'' width=''220px''><text x=''55'' y=''75'' font-size=''20''>or drop files here</text></svg>");
background-repeat: no-repeat;
}
El campo de archivo ahora se verá así:
Si usa asp.net, también podría querer este artículo. Escribí "Carga de archivos múltiples con barra de progreso y arrastrar y soltar": http://www.codeproject.com/Articles/818561/Multiple-file-upload-with-progress-bar-and-drag-an
No necesitaría usar un iframe para cargar pseudo ajax. Chrome y Safari admiten subidas de XHR2 con eventos de progreso para que pueda hacer barras de progreso, etc.
Para nuestra propia aplicación, arrastramos y soltamos solo para Firefox. Volvemos a la carga de iframe tradicional para otros. Para detectar que se admite arrastrar y soltar, ejecutamos este código:
if (typeof(window.File) == ''object'' && typeof(window.FileReader) == ''function'' && typeof(window.FileList) == ''object'') {
// DnD is supported!
}
Espero que esto sea útil para algunos.
Puede usar la biblioteca html5uploader: http://code.google.com/p/html5uploader/
Funciona con Firefox, Safari y Chrome.
Tengo algo trabajando en Chrome después de mucho, mucho, mucho trabajo de detective. Esto solo funciona en Chrome. En Safari, se congela. En Firefox, no me deja soltar el archivo. IE abre el archivo caído en su lugar. Incluso en Chrome, el método de arrastrar y soltar solo funciona una vez, por algún motivo, después del cual debe 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''));
puede usar FormData para almacenar el archivo y luego cargarlo. p.ej
function setUp(){
var dropContainer = document.getElementById("container");
dropContainer.addEventListener("drop",dropHandler,false);
dropContainer.addEventListener("dragenter", function(event){event.stopPropagation();event.preventDefault();}, false);
dropContainer.addEventListener("dragover", function(event){event.stopPropagation();event.preventDefault();}, false);
dropContainer.addEventListener("drop", dropHandler, false);
getResult()
}
function dropHandler(event){
var files = event.dataTransfer.files;
var count = files.length;
form = new FormData();
for(var i= 0;i<count;i++){
form.append("file"+i, files[i]);
}
sendData();
}
function sendData(){
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.open("POST", "/upload");
xhr.send(form);
var progressBar = document.getElementById(''progressBar'');
progressBar.style.display = ''block'';
progressBar.style.width = ''0px'';
}
la demostración está aquí (http://flexinnerp.appspot.com/) simplemente disfrútela :)