Start · Sprachen · JavaScript · Referenz · HTMLInputElement: cancel

HTMLInputElement: cancel

Ereignis

Wird auf einem <code>&lt;input type="file"&gt;</code> ausgelöst, wenn der Dateiauswahldialog abgebrochen wird oder dieselben Dateien erneut ausgewählt werden.

seit JavaScript Baseline 2023: Chrome 113, Edge 113, Firefox 91, S Kategorie: webapi

Signatur

inputElement.addEventListener("cancel", handler)

Beschreibung

Das cancel-Ereignis tritt bei einem <input type="file">-Element auf, wenn der Benutzer den Dateiauswahldialog ohne Änderung schließt, also mit der Esc-Taste, der Schaltfläche „Abbrechen“ oder durch Schließen des Dialogfensters. Es tritt außerdem auf, wenn der Benutzer genau dieselben Dateien wählt, die schon ausgewählt waren. In diesem Fall ändert sich der Wert nicht, deshalb kommt kein change-Ereignis.

Bisher gab es keinen zuverlässigen Weg festzustellen, ob ein Dateidialog ohne Auswahl geschlossen wurde. Man behalf sich mit focus-Tricks auf window. Mit cancel lassen sich Ladeanzeigen, deaktivierte Schaltflächen oder „Datei wird ausgewählt …“-Zustände sauber zurücksetzen.

Das Ereignis ist ein einfaches Event. Es steigt im DOM auf (bubbles) und ist nicht abbrechbar: preventDefault() hat keine Wirkung. Du kannst es mit addEventListener("cancel", …) oder über die Eigenschaft oncancel abonnieren.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Name des Ereignisses, hier immer "cancel".
$handler Pflicht (event: Event) => void Callback, der mit einem einfachen Event-Objekt aufgerufen wird. event.target ist das Eingabeelement.
$options boolean | AddEventListenerOptions false Optionen wie once, capture, passive oder signal (Abmelden über einen AbortController).

Beispiele

Abbruch des Dateidialogs erkennen

const input = document.querySelector('input[type="file"]');
const status = document.querySelector('#status');

input.addEventListener('change', () => {
  status.textContent = `${input.files.length} Datei(en) ausgewählt`;
});

input.addEventListener('cancel', () => {
  status.textContent = 'Auswahl abgebrochen oder unverändert.';
  console.log('Dateidialog abgebrochen');
});
Dateidialog abgebrochen

Ladezustand mit Promise zurücksetzen

// Öffnet den Dateidialog und liefert die Dateien oder null bei Abbruch
const pickFiles = (accept = '*/*') => new Promise((resolve) => {
  const input = document.createElement('input');
  input.type = 'file';
  input.accept = accept;
  input.multiple = true;

  input.addEventListener('change', () => resolve([...input.files]), { once: true });
  input.addEventListener('cancel', () => resolve(null), { once: true });

  input.showPicker?.() ?? input.click();
});

const button = document.querySelector('#upload');
button.addEventListener('click', async () => {
  button.disabled = true;
  const files = await pickFiles('image/*');
  button.disabled = false;
  console.log(files ? `Hochladen: ${files.map(f => f.name).join(', ')}` : 'Nichts gewählt');
});
Nichts gewählt

oncancel-Property und Abmelden des Listeners

const input = document.querySelector('#avatar');

// Variante 1: on-Property (ersetzt einen früheren Handler)
input.oncancel = (event) => {
  console.log('Abbruch bei', event.target.id, '| bubbles:', event.bubbles);
};

// Variante 2: addEventListener mit anschließendem removeEventListener
const onCancel = () => console.log('Einmalige Abbruch-Behandlung');
input.addEventListener('cancel', onCancel);
// später, z. B. nach dem ersten Upload:
input.removeEventListener('cancel', onCancel);

// Handler über die Property wieder entfernen
// input.oncancel = null;
Abbruch bei avatar | bubbles: true

// Wichtig · Fallstricke

  • Browser-Unterstützung: Erst seit Chrome/Edge 113, Firefox 91 und Safari 16.4 verfügbar. Ältere Browser lösen beim Abbruch gar kein Ereignis aus. Deshalb darf deine Logik nicht allein von cancel abhängen, zum Beispiel wenn ein Promise aufgelöst werden soll. Für ältere Browser brauchst du eine Ausweichlösung, etwa mit einem Zeitlimit oder über window-focus.
  • Gleiche Dateien erneut gewählt: Auch dann feuert cancel statt change. Soll dieselbe Datei erneut verarbeitet werden, setze vor dem Öffnen input.value = ''. Dann kommt wieder ein change-Ereignis.
  • Nicht abbrechbar: event.preventDefault() hat keine Wirkung, der Dialog ist dann schon geschlossen.
  • Bubbling: Anders als das cancel-Ereignis von <dialog> steigt dieses Ereignis auf. Ein cancel-Listener auf einem umgebenden <dialog> oder auf document empfängt daher auch Abbrüche von Dateifeldern. Prüfe im Handler event.target.
  • Ereignisse gibt es nur, wenn der Dialog durch eine Benutzeraktion geöffnet wurde (click() oder showPicker() innerhalb einer Benutzerinteraktion).