В этой статье я рассказываю о простом, но эффективном методе рекурсивной выборки содержимого каталогов с помощью операции перетаскивания. Вы можете использовать это для загрузки нескольких папок на сервер. Если вас интересует работающий код, можете сразу перейти к демонстрации stackblitz, которую я создал для этой статьи. Если вы заинтересованы в объяснении, пожалуйста, не стесняйтесь читать эту статью. Я думаю, что дальнейшее чтение поможет вам настроить код так, как вы хотите.

Демо StackBlitz



Контекст

Создал угловое приложение, чтобы продемонстрировать это, но вы можете использовать его в любой среде JavaScript. Нам нужен тег ‹div›, который будет действовать как зона перетаскивания. Мы можем сделать это, указав в теге прослушиватель событий ‘drop’. Чтобы упростить обнаружение зоны перетаскивания, мы также укажем еще два прослушивателя событий в теге ‹div›: события dragover и dragleave. Событие Dragover срабатывает, когда элементы находятся над зоной сброса. Событие Dragleave срабатывает, когда элементы покидают зону сброса. Кроме того, я также указал прослушиватель событий dragend, чтобы удалить выделение из зоны перетаскивания по окончании операции перетаскивания. На протяжении всей операции мы будем использовать единую структуру данных для хранения всех файлов: files: Array‹any›.

Пошаговая процедура

  1. Получите дескрипторы файловой системы для каждого элемента передачи данных (при перетаскивании элементы доступны через два разных свойства: event.dataTransfer.items и event.dataTransfer.files. Здесь мы используем event.dataTransfer.items, поскольку они более эффективны, чем файлы.
  • Мы будем использовать метод getAsFileSystemHandle() объекта DataTransferItem.
  • getAsFileSystemHandle() вернет обещание, которое будет выполнено с: FileSystemFileHandle, если элемент является файлом; FileSystemDirectoryHandle, если элемент является каталогом. Это показано на рисунке 2.

2. Переберите дескрипторы FileSystemHandles (FileSystemFileHandles и FileSystemDirectoryHandles), полученные на шаге 1, с помощью цикла for await of. Мы используем цикл for await, поскольку мы перебираем набор промисов, полученных из методов getAsFileSystemHandle() на шаге 1.

  • Если это FileSystemFileHandle, получите соответствующий объект File и добавьте его в массив файлов.
  • Если это FileSystemDirectoryHandle, мы рекурсивно получим все файлы под ним (включая файлы в подкаталогах), вызвав getFilesRecursively()

3. К концу шага 2 массив files будет содержать все файлы вместе с путями к ним. Мы храним информацию о пути в свойстве path_components. Это настраиваемое свойство, которое мы добавляем к объекту типа File.

Спасибо, что прочитали. Пожалуйста, не стесняйтесь оставлять свои мысли по этому поводу.