模拟放置文件事件
是否有可能使用JavaScript来模拟/伪造拖放事件? 如何testing这种types的事件?
举例来说,这个dnd上传示例页面 ,是否可以通过文件来触发“drop”事件,而不会实际上丢弃文件? 比方说点击一个button?
我已经开始写一个Sukuli脚本,可以控制鼠标,并做的伎俩,但我正在寻找一个更好的解决scheme。
编辑
@kol回答是摆脱拖放事件的好方法,但我仍然需要从我的电脑手动select一个文件。 这是我有兴趣模拟的一点。 有没有办法以编程方式创build文件variables?
var fileInput = document.getElementById('fileInput'), file = fileInput.files[0];
1.删除用户select的图像
我做了一个jsfiddle 。 这是你提到的html5demos.com页面的精简版本,但是:
- 我添加了一个
<input type="file">
标签,可以用来从本地计算机中select一个图像文件 - 我还添加了一个带有
onclick
处理程序的<input type="button">
标记,它通过直接调用 DND-targetdiv
标记的ondrop
事件处理程序来模拟“drop file”事件。
ondrop
处理程序如下所示:
holder.ondrop = function (e) { this.className = ''; e.preventDefault(); readfiles(e.dataTransfer.files); }
也就是说,我们必须把一个论点传给ondrop
,
- 有一个
dataTransfer
字段和一个files
数组子字段,其中包含选定的File
,和 - 有一个
preventDefault
方法(一个没有身体的函数会做)。
因此,“模拟放置”button的onclick
处理程序如下所示:
function simulateDrop() { var fileInput = document.getElementById('fileInput'), file = fileInput.files[0]; holder.ondrop({ dataTransfer: { files: [ file ] }, preventDefault: function () {} }); }
testing
- select一个图像文件(PNG,JPEG或GIF)
- 点击“模拟放置”button
结果
2.无需用户交互即可删除自动生成的testing文件( 仅适用于Google CHROME !!! )
我做了另一个jsfiddle 。 当页面被加载,一个函数被调用,其中:
- 创build一个文本文件到临时文件系统中
- 将这个文本文件加载并放到目标
<div>
; 然后 - 创build一个映像文件到临时文件系统中
- 加载并下载这个图像文件到目标
<div>
。
这个drop-simulator函数调用的代码如下:
(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 ); })();
自动生成的文本文件的内容以stringforms给出,图像文件的内容以base64编码的stringforms给出。 这些很容易改变。 例如,testing文本文件不仅可以包含纯文本,也可以包含HTML。 在这种情况下,不要忘记将textFile.contentType
字段从text/plain
更改为text/html
,并将此内容types添加到acceptedTypes
数组和previewfile
函数中。 testing图像也可以很容易地改变,你只需要一个图像到base64转换器 。
我不得不扩展拖放处理程序代码来处理除图像以外的文本文件:
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); } }
请注意,在加载jsfiddle之后 ,可以列出自动生成的文件以进行debugging:
结果
屏幕截图显示了模拟放置在自动生成的图像之前插入了自动生成的文本文件的内容。 DND-target <div>
的HTML代码如下所示:
<div id="holder" class=""> <p>hello, world</p> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggkFBTzlUWEwwWTRPSHdBQUFBQkpSVTVFcmtKZ2dnPT0=" width="250"> </div>
@kol回答是摆脱拖放事件的好方法,但我仍然需要从我的电脑手动select一个文件。 这是我有兴趣模拟的一点。 有没有办法以编程方式创build文件variables? -caiocpricci2
尝试这个
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()