Signatur
Beschreibung
Die schreibgeschützte Eigenschaft isDirectory der Schnittstelle FileSystemEntry gibt an, ob ein Eintrag ein Verzeichnis ist. Bei true ist das Objekt ein FileSystemDirectoryEntry. Sie können dann mit createReader() seinen Inhalt auflisten oder mit getFile() bzw. getDirectory() auf einzelne Kindeinträge zugreifen.
Einträge vom Typ FileSystemEntry erhalten Sie typischerweise über DataTransferItem.webkitGetAsEntry(), wenn Dateien oder Ordner per Drag & Drop abgelegt werden. Sie kommen auch aus HTMLInputElement.webkitEntries oder beim Lesen eines Verzeichnisses. Weil ein abgelegtes Element sowohl eine Datei als auch ein Ordner sein kann, brauchen Sie isDirectory (oder das Gegenstück isFile), um zu entscheiden, wie Sie weitermachen.
Meist rufen Sie die Eigenschaft in rekursiven Funktionen auf: Sie laufen einen abgelegten Ordnerbaum durch und sammeln dabei alle Dateien ein.
Rückgabewert
true, wenn der Eintrag ein Verzeichnis ist, sonst false.Beispiele
Abgelegte Elemente als Datei oder Ordner erkennen
const dropZone = document.querySelector('#drop-zone');
dropZone.addEventListener('dragover', (e) => e.preventDefault());
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
for (const item of e.dataTransfer.items) {
const entry = item.webkitGetAsEntry();
if (!entry) continue;
const art = entry.isDirectory ? 'Ordner' : 'Datei';
console.log(`${art}: ${entry.fullPath}`);
}
});
Ordnerbaum rekursiv durchlaufen und alle Dateien sammeln
// Liest alle Einträge eines Verzeichnisses (readEntries liefert Blöcke)
const readAllEntries = (dirEntry) => new Promise((resolve, reject) => {
const reader = dirEntry.createReader();
const result = [];
const readBatch = () => {
reader.readEntries((batch) => {
if (batch.length === 0) return resolve(result);
result.push(...batch);
readBatch();
}, reject);
};
readBatch();
});
const entryToFile = (fileEntry) =>
new Promise((resolve, reject) => fileEntry.file(resolve, reject));
const collectFiles = async (entry) => {
if (entry.isDirectory) {
const children = await readAllEntries(entry);
const nested = await Promise.all(children.map(collectFiles));
return nested.flat();
}
return [await entryToFile(entry)];
};
document.querySelector('#drop-zone').addEventListener('drop', async (e) => {
e.preventDefault();
const entries = [...e.dataTransfer.items]
.map((item) => item.webkitGetAsEntry())
.filter(Boolean);
const files = (await Promise.all(entries.map(collectFiles))).flat();
console.log(`${files.length} Dateien gefunden`);
});
Ordnerauswahl per input mit webkitdirectory prüfen
// <input type="file" id="picker" webkitdirectory multiple>
const picker = document.querySelector('#picker');
picker.addEventListener('change', () => {
const entries = picker.webkitEntries ?? [];
if (entries.length === 0) {
console.log('webkitEntries wird nicht unterstützt oder ist leer');
return;
}
const ordner = entries.filter((entry) => entry.isDirectory);
console.log(`Ausgewählte Ordner: ${ordner.map((d) => d.name).join(', ')}`);
});
// Wichtig · Fallstricke
- Nur lesbar: Wenn Sie
isDirectoryeinen Wert zuweisen, passiert nichts (im Strict-Modus gibt es einenTypeError). - Das Gegenteil ist nicht immer eine Datei: Laut Spezifikation sind
isDirectoryundisFilezwar gegensätzlich. Prüfen Sie im robusten Code trotzdem ausdrücklichisFile, bevor Siefile()aufrufen. - webkitGetAsEntry() nur synchron im drop-Handler: Nach dem Ereignis ist
DataTransferleer. Holen Sie deshalb alle Einträge ab, bevor das ersteawaitkommt. - readEntries() liefert Blöcke: Chrome gibt höchstens rund 100 Einträge pro Aufruf zurück. Rufen Sie die Methode so oft auf, bis ein leeres Array kommt.
- Kompatibilität: Chrome, Edge, Firefox und Safari unterstützen die API. Die Einstiegsmethoden haben aber weiterhin das Präfix
webkit. Für neuen Code, der Dateien lesen und schreiben soll, ist die File System Access API (FileSystemHandle.kind) die modernere Wahl, die aber nicht überall verfügbar ist. - Die API funktioniert nur mit Einträgen, die der Nutzer selbst auswählt oder ablegt. Beliebige Pfade im lokalen Dateisystem erreichen Sie damit nicht.