Start · Sprachen · JavaScript · Referenz · DataTransferItem.webkitGetAsEntry()

DataTransferItem.webkitGetAsEntry()

Methode

Gibt für ein per Drag &amp; Drop übergebenes Element ein <code>FileSystemFileEntry</code> oder <code>FileSystemDirectoryEntry</code> zurück, oder <code>null</code>, wenn es keine Datei ist.

seit JavaScript Baseline: alle modernen Browser (Chrome 13+, Firef Kategorie: webapi

Signatur

DataTransferItem.prototype.webkitGetAsEntry()

Beschreibung

Mit webkitGetAsEntry() bekommt man zu einem DataTransferItem einen Eintrag der File and Directory Entries API. Anders als getAsFile(), das nur ein File-Objekt liefert, zeigt der zurückgegebene Eintrag, ob ein Verzeichnis oder eine Datei abgelegt wurde. Das ist der übliche Weg, um beim Ablegen per Drag & Drop ganze Ordner samt Unterordnern rekursiv einzulesen.

Das Ergebnis ist ein FileSystemEntry, genauer ein FileSystemFileEntry (isFile === true) oder ein FileSystemDirectoryEntry (isDirectory === true). Bei Dateien kommt man mit entry.file(callback) an das File-Objekt. Bei Verzeichnissen liest man den Inhalt über entry.createReader().readEntries(callback) aus.

Die Methode ist nur für Elemente mit kind === "file" sinnvoll. Bei Text- oder URL-Elementen (kind === "string") gibt sie null zurück. Trotz des webkit-Präfixes ist die Methode standardisiert und wird von allen modernen Browsern unter genau diesem Namen unterstützt. Eine Variante ohne Präfix gibt es nicht.

Rückgabewert

Typ
FileSystemFileEntry | FileSystemDirectoryEntry | null
Beschreibung
Ein FileSystemEntry-Objekt für die abgelegte Datei bzw. das abgelegte Verzeichnis, oder null, wenn das Element keine Datei ist.

Beispiele

Abgelegte Elemente als Datei oder Ordner erkennen

const dropZone = document.querySelector('#drop-zone');

dropZone.addEventListener('dragover', (event) => {
  event.preventDefault(); // Ablegen erlauben
});

dropZone.addEventListener('drop', (event) => {
  event.preventDefault();
  for (const item of event.dataTransfer.items) {
    const entry = item.webkitGetAsEntry();
    if (!entry) continue; // kein Datei-Element
    console.log(entry.isDirectory ? 'Ordner:' : 'Datei:', entry.fullPath);
  }
});
Ordner: /fotos Datei: /notizen.txt

Ordner rekursiv einlesen (mit Promises)

// Callback-APIs in Promises verpacken
const getFile = (fileEntry) =>
  new Promise((resolve, reject) => fileEntry.file(resolve, reject));

// readEntries liefert Einträge in Blöcken – so lange aufrufen, bis ein leeres Array kommt
const readAllEntries = async (dirEntry) => {
  const reader = dirEntry.createReader();
  const all = [];
  let batch;
  do {
    batch = await new Promise((resolve, reject) => reader.readEntries(resolve, reject));
    all.push(...batch);
  } while (batch.length > 0);
  return all;
};

const collectFiles = async (entry) => {
  if (entry.isFile) {
    const file = await getFile(entry);
    return [{ path: entry.fullPath, file }];
  }
  const children = await readAllEntries(entry);
  const nested = await Promise.all(children.map(collectFiles));
  return nested.flat();
};

document.body.addEventListener('dragover', (e) => e.preventDefault());
document.body.addEventListener('drop', async (event) => {
  event.preventDefault();
  // Einträge SOFORT (synchron) holen – nach dem ersten await ist die DataTransferItemList leer
  const entries = [...event.dataTransfer.items]
    .map((item) => item.webkitGetAsEntry())
    .filter(Boolean);

  const results = (await Promise.all(entries.map(collectFiles))).flat();
  results.forEach(({ path, file }) => console.log(path, file.size, 'Bytes'));
});
/projekt/index.html 1532 Bytes /projekt/css/style.css 842 Bytes

Fallback auf getAsFile() ohne Ordner-Unterstützung

const handleItem = (item) => {
  if (item.kind !== 'file') return null;
  if (typeof item.webkitGetAsEntry === 'function') {
    return item.webkitGetAsEntry();
  }
  // Ältere Umgebung: nur einzelne Dateien möglich
  return item.getAsFile();
};

document.addEventListener('dragover', (e) => e.preventDefault());
document.addEventListener('drop', (event) => {
  event.preventDefault();
  const results = [...event.dataTransfer.items].map(handleItem);
  console.log(results);
});
[FileSystemDirectoryEntry, FileSystemFileEntry]

// Wichtig · Fallstricke

  • Nur synchron im drop-Handler aufrufen: Der Browser gibt die DataTransferItemList nach dem Ereignis frei. Wer die Methode erst nach einem await oder in einem setTimeout aufruft, bekommt leere Listen oder null. Deshalb zuerst alle Einträge einsammeln und erst danach asynchron verarbeiten.
  • readEntries() liefert Einträge in Blöcken: Chrome gibt höchstens 100 Einträge pro Aufruf zurück. Man muss readEntries() daher so lange erneut aufrufen, bis ein leeres Array kommt, sonst fehlen bei großen Ordnern Dateien.
  • Die Methode funktioniert nur beim Ereignis drop. Bei dragover/dragenter sind die Daten aus Datenschutzgründen geschützt (Protected Mode).
  • Bei Elementen mit kind === "string" ist der Rückgabewert null. Vor dem Zugriff also immer prüfen.
  • Die Einträge sind nur lesbar. Schreiben ist nicht möglich, und fullPath ist ein virtueller Pfad relativ zur Auswahl, kein echter Pfad im Dateisystem.
  • Trotz des Präfixes ist die Methode in Chrome, Edge, Firefox und Safari verfügbar. Für neuere Anwendungen in Chromium-Browsern gibt es alternativ DataTransferItem.getAsFileSystemHandle() (File System Access API) mit Promise-basierter API und Schreibzugriff. Diese Methode wird aber noch nicht von allen Browsern unterstützt.