模拟放置文件事件 [英] Simulate drop file event

查看:287
本文介绍了模拟放置文件事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用javascript来模拟/假的放置事件?如何测试这种类型的事件?



以此为例,这个dnd上传示例。



除了图像之外,我不得不扩展下拉列表处理程序代码来处理文本文件:

  acceptedTypes = {
'text / plain':true,//< - 我添加了
'image / png':true,
'image / jpeg':true,
'image / gif':true
},

...

函数预览文件(文件){
if(tests.filereader === true&& acceptTypes [file.type] === true){
var reader = new FileReader();
if(file.type ==='text / plain'){//< - 我添加了这个分支
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; //一个假的大小
holder.appendChild(image);
};
reader.readAsDataURL(file);
}
} else {
holder.innerHTML + ='< p>上传'+ file.name +','+ file.size +'B,'+ file.type;
console.log(file);
}
}

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



< img src =https://i.stack.imgur.com/KefN7.pngalt =临时文件系统>



结果





截图显示,模拟的下拉插入自动生成的图像之前的自动生成的文本文件的内容。 DND目标< div> 的HTML代码如下所示:

 < div id =holderclass => 
< p> hello,world< / p>
< img src =data:image / png; base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4 // 8 / w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggkFBTzlUWEwwWTRPSHdBQUFBQkpSVTVFcmtKZ2dnPT0 =width =250>
< / div>


Is it possible to simulate/fake the drop event using javascript only? How to test this type of event?

Take for example this dnd upload sample page , is it possible to trigger the "drop" event with a file without actually dropping a file there? Let's say clicking on a button?

I have started writing a Sukuli script that can control the mouse and do the trick but I was looking for a better solution.

EDIT

@kol answer is a good way to get rid of the drag and drop event but I still have to manually select a file from my computer. This is the bit I am interested in simulating. Is there a way to create a file variable programatically?

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

解决方案

1. Dropping image selected by the user

I've made a jsfiddle. It's a stripped-down version of the html5demos.com page you've referred to, but:

  • I added an <input type="file"> tag which can be used to select an image file from the local computer, and
  • I also added an <input type="button"> tag with an onclick handler, which simulates the "drop file" event by directly calling the ondrop event handler of the DND-target div tag.

The ondrop handler looks like this:

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

That is, we have to pass an argument to ondrop, which

  • has a dataTransfer field with a files array subfield, which contains the selected File, and
  • has a preventDefault method (a function with no body will do).

So the onclick handler of the "Simulate drop" button is the following:

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

Test

  1. Select an image file (png, jpeg, or gif)
  2. Click on the "Simulate drop" button

Result

2. Dropping autogenerated test files without user interaction (GOOGLE CHROME ONLY!!!)

I've made another jsfiddle. When the page is loaded, a function gets called, which:

  • creates a text file into the temporary file system, and
  • loads and drops this text file into the target <div>; then
  • creates an image file into the temporary file system, and
  • loads and drops this image file into the target <div>.

The code of this drop-simulator function call is the following:

(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
    );    
})();

The content of the auto-generated text file is given as a string, and the content of the image file is given as a base64-encoded string. These are easy to change. For example, the test text file can contain not just plain text, but HTML too. In this case, don't forget to change the textFile.contentType field from text/plain to text/html, and to add this content type to the acceptedTypes array and to the previewfile function. The test image can also be changed easily, you just need an image-to-base64 converter.

I had to extend the drop handler code to handle text files in addition to images:

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);
    }
}

Note that after loading the jsfiddle, the autogenerated files can be listed for debugging purposes:

Result

The screenshot shows that the simulated drop inserted the content of the autogenerated text file before the autogenerated image. The HTML code of the DND-target <div> looks like this:

<div id="holder" class="">
    <p>hello, world</p>
    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggkFBTzlUWEwwWTRPSHdBQUFBQkpSVTVFcmtKZ2dnPT0=" width="250">
</div>

这篇关于模拟放置文件事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆