To enable directory upload, certain new APIs are needed which are outlined in the directory upload spec proposal. There are two ways we can upload files and directories: a file input with the "directory" attribute, or an element with a drop event listener. Below are examples of these methods in action using the new APIs (the polyfill only works in Chrome).
<input type="file" id="fileInput" allowdirs multiple /> <script type="text/javascript"> document.addEventListener('DOMContentLoaded', function(event) { document.getElementById('fileInput').addEventListener('change', function() { var uploadFile = function(file, path) { console.log(path, file); // handle file uploading }; var iterateFilesAndDirs = function(filesAndDirs, path) { for (var i = 0; i < filesAndDirs.length; i++) { if (typeof filesAndDirs[i].getFilesAndDirectories === 'function') { var path = filesAndDirs[i].path; // this recursion enables deep traversal of directories filesAndDirs[i].getFilesAndDirectories().then(function(subFilesAndDirs) { // iterate through files and directories in sub-directory iterateFilesAndDirs(subFilesAndDirs, path); }); } else { uploadFile(filesAndDirs[i], path); } } }; // begin by traversing the chosen files and directories if ('getFilesAndDirectories' in this) { this.getFilesAndDirectories().then(function(filesAndDirs) { iterateFilesAndDirs(filesAndDirs, '/'); }); } }); }); </script>
<div id="dropDiv">Drag & drop your files here!</div> <script type="text/javascript"> document.addEventListener('DOMContentLoaded', function(event) { document.getElementById('dropDiv').addEventListener('drop', function (e) { e.stopPropagation(); e.preventDefault(); var uploadFile = function(file, path) { console.log(path, file); // handle file uploading }; var iterateFilesAndDirs = function(filesAndDirs, path) { for (var i = 0; i < filesAndDirs.length; i++) { if (typeof filesAndDirs[i].getFilesAndDirectories === 'function') { var path = filesAndDirs[i].path; // this recursion enables deep traversal of directories filesAndDirs[i].getFilesAndDirectories().then(function(subFilesAndDirs) { // iterate through files and directories in sub-directory iterateFilesAndDirs(subFilesAndDirs, path); }); } else { uploadFile(filesAndDirs[i], path); } } }; // begin by traversing the chosen files and directories if ('getFilesAndDirectories' in e.dataTransfer) { e.dataTransfer.getFilesAndDirectories().then(function(filesAndDirs) { iterateFilesAndDirs(filesAndDirs, '/'); }); } }); }); </script>