Assumption: A local HTML/Javascript webpage that has access to file://
At the start of a drag on a draggable HTML element, in the event handler function dragStart(e), how do I add a File object so that it is recognized as a file and ends up in the dataTransfer.files list?
Ex:
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]);
}
}
Specifically, it needs to work on Chrome/Chromium. And, we can assume that the file exists on the local drive. Basically, I want the same data available then when a file is dragged from Windows Explorer to a HTML page on an element that is droppable.
I know that this exists in Chrome:
e.originalEvent.dataTransfer.setData("DownloadURL", fileType + ":" + name + ":" + filePath);
which downloads the file. But this is not what I want, because I want to assume that this is an existing file and that the original file must be accessed.
You can use the approach posted by @kol at Simulate drop file event
That is, we have to pass an argument to ondrop, which
- has a
dataTransferfield with afilesarray subfield, which contains the selectedFile, and- a
preventDefaultmethod (a function with no body will do).
adjusted below to attach .addEventListener("drop") to drop element at dragstart event, with File objects passed to a bound function with Function.prototype.bind() which returns the appropriate object described above, with once:true passed at third parameter to .addEventListener(), to call drop event at most once for each dragstart event where File objects are accessed or created.
FileList object is read only, an Array is used to store File object at dataTransfer.files property within a plain javascript object at event handlers.
Note: The
FileListinterface should be considered "at risk" since the general trend on the Web Platform is to replace such interfaces with theArrayplatform object in ECMAScript [ECMA-262]. In particular, this means syntax of the sortfilelist.item(0)is at risk; most other programmatic use ofFileListis unlikely to be affected by the eventual migration to anArraytype.
If event.dataTransfer.files at dragstart event contains File objects, iterate FileList and push each File object to files array.
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>
plnkr http://plnkr.co/edit/ihQqs4t2zOg2XhIuNwal?p=preview
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With