<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="utf-8" />
<title>接收文件(夹)</title>
</head>
<body>
<input type="file" multiple />
<div>可选择、拖拽、粘贴</div>
</body>
</html>
var nr = {
/**
* 接收文件
* @param {*} fn 回调
* @param {*} fileNode 选择文件控件
* @param {*} dragNode 拖拽区域,默认全局
*/
receiveFiles: function (fn, fileNode, dragNode) {
dragNode = dragNode || document;
//拖拽
dragNode.addEventListener('dragover', (event) => {
if (!(fileNode && fileNode.contains(event.target))) {
event.preventDefault();
event.stopPropagation();
}
});
dragNode.addEventListener("drop", (event) => {
if (!(fileNode && fileNode.contains(event.target))) {
event.preventDefault();
var items = event.dataTransfer.items;
nr.readDataTransferItems(items).then(files => {
if (files.length) {
fn(files, 'drag');
}
});
}
});
//浏览
if (fileNode) {
fileNode.addEventListener("change", function () {
var files = this.files;
if (files.length) {
fn(files, 'change');
}
});
}
//粘贴
document.addEventListener('paste', function (event) {
var items = event.clipboardData.items, files = [];
for (let index = 0; index < items.length; index++) {
var blob = items[index].getAsFile();
blob && files.push(blob);
}
if (files.length) {
fn(files, 'paste');
}
})
},
readDataTransferItems: (items) => new Promise((resolve) => {
var parr = [], list = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
var itemEntry = item.webkitGetAsEntry();
if (itemEntry != null) {
parr.push(nr.readDataTransferItemEntry(itemEntry));
} else {
var file = item.getAsFile();
if (file) {
list.push(file);
}
}
}
Promise.all(parr).then((arr) => {
arr.forEach(x => {
if (x.length) {
list = list.concat(x)
} else {
list.push(x)
}
})
resolve(list)
})
}),
readDataTransferItemEntry: (itemEntry, path) => new Promise((resolve) => {
path = path || "";
if (itemEntry.isFile) {
itemEntry.file(file => {
if (path != "") {
file.fullPath = path + file.name; // 兼容路径丢失
}
resolve(file)
})
} else if (itemEntry.isDirectory) {
var dirReader = itemEntry.createReader();
dirReader.readEntries((entries) => {
var parr = [];
for (var i = 0; i < entries.length; i++) {
parr.push(nr.readDataTransferItemEntry(entries[i], path + itemEntry.name + "/"))
}
Promise.all(parr).then((arr) => {
var list = [];
arr.forEach(x => {
if (x.length) {
list = list.concat(x)
} else {
list.push(x)
}
})
resolve(list)
})
});
}
}),
}
nr.receiveFiles((files, ename) => {
console.debug(ename, files)
}, document.querySelector('input'))