javascript - ejemplos - drag and drop js
Simular evento de archivo desplegable (2)
¿Es posible simular / falsificar el evento drop usando javascript solamente? ¿Cómo probar este tipo de evento?
Tomemos como ejemplo esta página de carga y carga de archivos, ¿es posible desencadenar el evento "soltar" con un archivo sin dejar caer un archivo allí? Digamos que presionar un botón?
Empecé a escribir un script de Sukuli que puede controlar el mouse y hacer el truco, pero estaba buscando una solución mejor.
EDITAR
La respuesta de @kol es una buena manera de deshacerse del evento de arrastrar y soltar, pero aún tengo que seleccionar manualmente un archivo de mi computadora. Este es el bit que me interesa simular. ¿Hay alguna manera de crear una variable de archivo programáticamente?
var fileInput = document.getElementById(''fileInput''),
file = fileInput.files[0];
La respuesta de @kol es una buena manera de deshacerse del evento de arrastrar y soltar, pero aún tengo que seleccionar manualmente un archivo de mi computadora. Este es el bit que me interesa simular. ¿Hay alguna manera de crear una variable de archivo programáticamente? -caiocpricci2
Prueba esto
function createFile(create) {
var create = ["<!doctype html><div>file</div>"];
var blob = new Blob([create], {"type" : "text/html"});
return ( blob.size > 0 ? blob : "file creation error" )
};
createFile()
1. Caída de la imagen seleccionada por el usuario
He hecho un jsfiddle . Es una versión simplificada de la página html5demos.com a la que se ha referido, pero:
- Agregué una etiqueta
<input type="file">
que se puede usar para seleccionar un archivo de imagen de la computadora local, y - También agregué una etiqueta
<input type="button">
con un controladoronclick
, que simula el evento "drop file" llamando directamente al controlador de eventoondrop
de la etiquetadiv
DND-target.
El controlador de ondrop
tiene este aspecto:
holder.ondrop = function (e) {
this.className = '''';
e.preventDefault();
readfiles(e.dataTransfer.files);
}
Es decir, tenemos que pasar un argumento a ondrop
, que
- tiene un campo de
dataTransfer
con un subcampo de matriz defiles
, que contiene elFile
seleccionado, y - tiene un método
preventDefault
(una función sin cuerpo lo hará).
Por lo tanto, el controlador onclick
del botón "Simular soltar" es el siguiente:
function simulateDrop() {
var fileInput = document.getElementById(''fileInput''),
file = fileInput.files[0];
holder.ondrop({
dataTransfer: { files: [ file ] },
preventDefault: function () {}
});
}
Prueba
- Seleccione un archivo de imagen (png, jpeg o gif)
- Haga clic en el botón "Simular soltar"
Resultado
2. Eliminando archivos de prueba autogenerados sin interacción del usuario (¡ GOOGLE CHROME SOLAMENTE! )
He hecho otro jsfiddle . Cuando se carga la página, se llama a una función, que:
- crea un archivo de texto en el sistema de archivos temporal, y
- carga y suelta este archivo de texto en el objetivo
<div>
; entonces - crea un archivo de imagen en el sistema de archivos temporal, y
- carga y suelta este archivo de imagen en el objetivo
<div>
.
El código de esta llamada a la función drop-simulator es el siguiente:
(function () {
var fileErrorHandler = function (e) {
var msg = "";
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = "QUOTA_EXCEEDED_ERR";
break;
case FileError.NOT_FOUND_ERR:
msg = "NOT_FOUND_ERR";
break;
case FileError.SECURITY_ERR:
msg = "SECURITY_ERR";
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = "INVALID_MODIFICATION_ERR";
break;
case FileError.INVALID_STATE_ERR:
msg = "INVALID_STATE_ERR";
break;
default:
msg = "Unknown Error";
break;
};
console.log("Error: " + msg);
},
requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem,
dropFile = function (file) {
holder.ondrop({
dataTransfer: { files: [ file ] },
preventDefault: function () {}
});
};
if (!requestFileSystem) {
console.log("FileSystem API is not supported");
return;
}
requestFileSystem(
window.TEMPORARY,
1024 * 1024,
function (fileSystem) {
var textFile = {
name: "test.txt",
content: "hello, world",
contentType: "text/plain"
},
imageFile = {
name: "test.png",
content: "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",
contentType: "image/png",
contentBytes: function () {
var byteCharacters = atob(this.content),
byteArrays = [], offset, sliceSize = 512, slice, byteNumbers, i, byteArray;
for (offset = 0; offset < byteCharacters.length; offset += sliceSize) {
slice = byteCharacters.slice(offset, offset + sliceSize);
byteNumbers = new Array(slice.length);
for (i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return byteArrays;
}
};
// Create and drop text file
fileSystem.root.getFile(
textFile.name,
{ create: true },
function (fileEntry) {
fileEntry.createWriter(
function (fileWriter) {
fileWriter.onwriteend = function(e) {
console.log("Write completed (" + textFile.name + ")");
fileSystem.root.getFile(
textFile.name,
{},
function (fileEntry) {
fileEntry.file(
function (file) {
dropFile(file);
},
fileErrorHandler
);
},
fileErrorHandler
);
};
fileWriter.onerror = function(e) {
console.log("Write failed (" + textFile.name + "): " + e.toString());
};
fileWriter.write(new Blob([ textFile.content ], { type: textFile.contentType }));
},
fileErrorHandler
);
},
fileErrorHandler
);
// Create and drop image file
fileSystem.root.getFile(
imageFile.name,
{ create: true },
function (fileEntry) {
fileEntry.createWriter(
function (fileWriter) {
fileWriter.onwriteend = function(e) {
console.log("Write completed (" + imageFile.name + ")");
fileSystem.root.getFile(
imageFile.name,
{},
function (fileEntry) {
fileEntry.file(
function (file) {
dropFile(file);
},
fileErrorHandler
);
},
fileErrorHandler
);
};
fileWriter.onerror = function(e) {
console.log("Write failed (" + imageFile.name + "): " + e.toString());
};
fileWriter.write(new Blob(imageFile.contentBytes(), { type: imageFile.contentType }));
},
fileErrorHandler
);
},
fileErrorHandler
);
},
fileErrorHandler
);
})();
El contenido del archivo de texto generado automáticamente se da como una cadena, y el contenido del archivo de imagen se da como una cadena codificada en base64. Estos son fáciles de cambiar Por ejemplo, el archivo de texto de prueba puede contener no solo texto plano, sino también HTML. En este caso, no olvide cambiar el campo textFile.contentType
de text/plain
a text/html
, y agregar este tipo de contenido a la matriz acceptedTypes
ya la función de vista previewfile
. La imagen de prueba también se puede cambiar fácilmente, solo necesita un convertidor de imagen a base64 .
Tuve que extender el código del controlador de caída para manejar archivos de texto además de imágenes:
acceptedTypes = {
''text/plain'': true, // <-- I added this
''image/png'': true,
''image/jpeg'': true,
''image/gif'': true
},
...
function previewfile(file) {
if (tests.filereader === true && acceptedTypes[file.type] === true) {
var reader = new FileReader();
if (file.type === ''text/plain'') { // <-- I added this branch
reader.onload = function (event) {
var p = document.createElement("p");
p.innerText = event.target.result;
holder.appendChild(p);
}
reader.readAsText(file);
} else {
reader.onload = function (event) {
var image = new Image();
image.src = event.target.result;
image.width = 250; // a fake resize
holder.appendChild(image);
};
reader.readAsDataURL(file);
}
} else {
holder.innerHTML += ''<p>Uploaded '' + file.name + '', '' + file.size + '' B, '' + file.type;
console.log(file);
}
}
Tenga en cuenta que después de cargar el jsfiddle , los archivos autogenerados se pueden enumerar para fines de depuración:
Resultado
La captura de pantalla muestra que la gota simulada insertó el contenido del archivo de texto autogenerado antes de la imagen autogenerada. El código HTML del DND-target <div>
ve así:
<div id="holder" class="">
<p>hello, world</p>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggkFBTzlUWEwwWTRPSHdBQUFBQkpSVTVFcmtKZ2dnPT0=" width="250">
</div>