<!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'))