标题 View
公开
私有分享码
评论
标签
<!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'))