1)拖拽方面的重點是:ondragover 事件 和 ondrop 事件
ondragover 是必須的,ondragover 事件里禁用掉 html 的默認事件,否則 ondrop 事件將無效(直接捕捉不到ondrop事件了)
dropzone.addEventListener("dragover", function(event) {
event.preventDefault();
}, false);
2)讀取目錄用到的 webApi 主要有: FileSystemFileEntry、FileSystemDirectoryEntry 和 FileSystemDirectoryReader
3)詳情說明及示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>H5 拖拽讀取文件和文件夾</title> <style type="text/css"> #dropzone { text-align: center; width: 300px; height: 100px; margin: 10px; padding: 10px; border: 4px dashed red; border-radius: 10px; } #boxtitle { display: table-cell; vertical-align: middle; text-align: center; color: black; font: bold 2em "Arial", sans-serif; width: 300px; height: 100px; } body { font: 14px "Arial", sans-serif; } </style> </head> <body> <p> Drag files and/or directories to the box below! </p> <div id="dropzone"> <div id="boxtitle"> Drop Files Here </div> </div> <h2>Directory tree:</h2> <ul id="listing"> </ul> <script type="text/javascript"> let dropzone = document.getElementById("dropzone"); let listing = document.getElementById("listing"); /** * 讀取文件 * @param item FileSystemDirectoryEntry 對象實例(目錄實體) * @param container 顯示容器 * @return void */ function scanFiles(item, container) { let elem = document.createElement("li"); elem.innerHTML = item.name; container.appendChild(elem); // 如果是目錄,則遞歸讀取 if (item.isDirectory) { // 使用目錄實體來創建 FileSystemDirectoryReader 實例 let directoryReader = item.createReader(); let directoryContainer = document.createElement("ul"); container.appendChild(directoryContainer); // 上面只是創建了 reader 實例,現在使用 reader 實例來讀取 目錄實體(讀取目錄內容) directoryReader.readEntries(function(entries) { // 循環目錄內容 entries.forEach(function(entry) { // 處理內容(遞歸) scanFiles(entry, directoryContainer); }); }); } } // 此事件是必須的,且要阻止默認事件 dropzone.addEventListener("dragover", function(event) { event.preventDefault(); }, false); // 拖拽結束時觸發 dropzone.addEventListener("drop", function(event) { // 拖拽(轉移)的對象列表 let items = event.dataTransfer.items; event.preventDefault(); listing.innerHTML = ""; for (let i=0; i<items.length; i++) { // file 對象(按實例拖拽的內容)轉換成 FileSystemFileEntry 對象 或 FileSystemDirectoryEntry 對象 let item = items[i].webkitGetAsEntry(); if (item) { // 讀取文件 scanFiles(item, listing); } } }, false); </script> </body> </html>
4)用到的其他 Api:
https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/dataTransfer
https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem
https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/webkitGetAsEntry
5)官方原版示例:
https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryReader/readEntries