模拟丢弃文件事件

时间:2014-03-12 23:11:15

标签: javascript jquery html5 testing drag-and-drop

是否可以仅使用javascript模拟/伪造掉落事件?如何测试此类事件?

以此dnd上传示例page为例,是否可以使用文件触发“drop”事件而不实际丢弃文件?我们说点击一个按钮?

我已经开始编写一个可以控制鼠标并执行操作的Sukuli脚本,但我正在寻找更好的解决方案。

修改

@kol答案是摆脱拖放事件的好方法,但我仍然需要从我的电脑中手动选择一个文件。这是我对模拟感兴趣的一点。有没有办法以编程方式创建文件变量?

var fileInput = document.getElementById('fileInput'),
file = fileInput.files[0];    

2 个答案:

答案 0 :(得分:18)

<强> 1。删除用户选择的图像

我做了jsfiddle。它是您提到的html5demos.com page的简化版本,但是:

  • 我添加了<input type="file">标记,可用于从本地计算机中选择图像文件,
  • 我还添加了一个带有<input type="button">处理程序的onclick标记,该处理程序模拟&#34; drop文件&#34; 直接调用DND目标ondrop标记的div事件处理程序的事件。

ondrop处理程序如下所示:

holder.ondrop = function (e) {
    this.className = '';
    e.preventDefault();
    readfiles(e.dataTransfer.files);
}

也就是说,我们必须将参数传递给ondrop,其中

  • dataTransfer字段带有files数组子字段,其中包含所选的File
  • preventDefault方法(没有正文的函数会这样做)。

所以&#34; Simulate drop&#34;的onclick处理程序按钮如下:

function simulateDrop() {
    var fileInput = document.getElementById('fileInput'),
        file = fileInput.files[0];        
    holder.ondrop({ 
        dataTransfer: { files: [ file ] }, 
        preventDefault: function () {} 
    });
}

<强>测试

  1. 选择图像文件(png,jpeg或gif)
  2. 点击&#34;模拟下拉&#34;按钮
  3. <强>结果

    Result

    <强> 2。在没有用户交互的情况下删除自动生成的测试文件(GOOGLE CHROME ONLY!!!

    我做了另一个jsfiddle。加载页面时,会调用一个函数,其中包括:

    • 在临时文件系统中创建一个文本文件,
    • 将此文本文件加载并删除到目标<div>;然后
    • 在临时文件系统中创建一个图像文件,
    • 将此图片文件加载到目标<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
        );    
    })();
    

    自动生成的文本文件的内容以字符串形式给出,图像文件的内容以base64编码的字符串形式给出。这些很容易改变。例如,测试文本文件不仅可以包含纯文本,还可以包含HTML。在这种情况下,请勿忘记将textFile.contentType字段从text/plain更改为text/html,并将此内容类型添加到acceptedTypes数组和{ {1}}功能。测试图像也可以轻松更改,只需image-to-base64 converter

    除了图像之外,我还必须扩展drop handler代码来处理文本文件:

    previewfile

    请注意,加载jsfiddle后,可以列出自动生成的文件以进行调试:

    Temporary file system

    <强>结果

    Result

    屏幕截图显示模拟的drop在自动生成的图像之前插入了自动生成的文本文件的内容。 DND目标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); } } 的HTML代码如下所示:

    <div>

答案 1 :(得分:4)

  

@kol回答是摆脱拖放事件的好方法,但我   仍然必须从我的电脑手动选择一个文件。这是有点   我对模拟很感兴趣。有没有办法创建一个文件   变量编程? -caiocpricci2

试试这个

function createFile() {
  var create = ["<!doctype html><div>file</div>"];
  var blob = new Blob([create], {"type" : "text/html"});
  return ( blob.size > 0 ? blob : "file creation error" )
};
createFile()