假设:一个可以访问 file://的本地 HTML/Javascript 网页
在可拖动的 HTML 元素上开始拖动时,在事件处理函数 dragStart(e)
中,我如何添加一个 File 对象,以便它被识别为一个文件并结束在 dataTransfer.files
列表中?
例如:
function dragStart(e){
var file = getSomeFileObjFromSomewhere();
e.originalEvent.dataTransfer.effectAllowed = "all";
e.originalEvent.dataTransfer.setData("file", file);
console.log("\nFiles:");
i = 0;
var files = e.originalEvent.dataTransfer.files,
len = files.length;
for (; i < len; i++) {
console.log("\nIndex: " + i + "\nFilename: " + files[i].name);
console.log("Type: " + files[i].type);
console.log("Size: " + files[i].size + " bytes");
console.dir(files[i]);
}
}
具体来说,它需要在 Chrome/Chromium 上运行。并且,我们可以假设该文件存在于本地驱动器上。基本上,当将文件从 Windows 资源管理器拖动到可放置元素上的 HTML 页面时,我希望获得相同的数据。
我知道这存在于 Chrome 中:
e.originalEvent.dataTransfer.setData("DownloadURL", fileType + ":" + name + ":" + filePath);
下载文件。但这不是我想要的,因为我想假设这是一个现有文件并且必须访问原始文件。
最佳答案
您可以使用@kol 在 Simulate drop file event 发布的方法
That is, we have to pass an argument to ondrop, which
- has a
dataTransfer
field with afiles
array subfield, which contains the selectedFile
, and- a
preventDefault
method (a function with no body will do).
调整如下附.addEventListener("drop")
至 drop
元素位于 dragstart
事件,与 File
使用 Function.prototype.bind()
传递给绑定(bind)函数的对象它返回上述适当的对象,带有 once:true
在第三个参数传递给 .addEventListener()
, 调用 drop
每个事件最多一次 dragstart
事件地点 File
访问或创建对象。
FileList
对象是只读的,一个 Array
用于存储File
对象在 dataTransfer.files
平原内的属性(property)javascript
事件处理程序中的对象。
Note: The
FileList
interface should be considered "at risk" since the general trend on the Web Platform is to replace such interfaces with theArray
platform object in ECMAScript [ECMA-262]. In particular, this means syntax of the sortfilelist.item(0)
is at risk; most other programmatic use ofFileList
is unlikely to be affected by the eventual migration to anArray
type.
如果event.dataTransfer.files
在dragstart
事件包含 File
对象,迭代 FileList
并推送每个 File
反对 files
数组。
var drag = document.getElementById("drag")
var drop = document.getElementById("drop")
function handleDrop(evt) {
evt.preventDefault();
console.log(evt.dataTransfer.files);
}
function getSomeFileObjFromSomewhere() {
var data = ["abc", "def"];
var files = [];
for (var i = 0; i < data.length; i++) {
files.push(new File([data[i]], data[i] + ".text", {
type: "text/plain",
lastModified: new Date().getTime()
}));
}
return files
}
function dataTransferFileObject(files) {
return {
preventDefault: function() {},
dataTransfer: {
files: Array.isArray(files) ? files : [files]
}
}
}
drag.addEventListener("dragstart", function dragStart(e) {
var files = getSomeFileObjFromSomewhere();
e.dataTransfer.effectAllowed = "all";
console.log("\nFiles:");
for (let i = 0; i < files.length; i++) {
var {name, size, type} = files[i];
console.log("\nFilename: " + name);
console.log("Type: " + type);
console.log("Size: " + size + " bytes");
}
// if `e.dataTransfer.files`, push `File` objects dragged
// to `files` array
if (e.dataTransfer.files) {
for (let file of e.dataTransfer.files) {
files.push(file);
}
}
drop.addEventListener("drop"
, handleDrop.bind(drop, dataTransferFileObject(files))
, {once: true});
});
drop.addEventListener("dragover", function(evt) {
evt.preventDefault()
});
div {
width: 50px;
height: 50px;
padding: 10px;
margin: 10px;
}
div:nth-child(1) {
border: 2px dotted blue;
}
div:nth-child(2) {
border: 2px dotted green;
}
<div draggable="true" id="drag">drag</div>
<div droppable="true" id="drop" webkitdropzone="webkitdropzone">drop</div>
关于javascript - 如何使用 Javascript 将文件添加到现有的 dataTransfer 对象中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24496989/