Start · Sprachen · JavaScript · Referenz · Element: contextmenu

Element: contextmenu

Ereignis

Wird ausgelöst, wenn der Benutzer ein Kontextmenü öffnen will, etwa per Rechtsklick, mit der Kontextmenü-Taste oder mit <code>Umschalt+F10</code>.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

element.addEventListener("contextmenu", handler)

Beschreibung

Das Ereignis contextmenu wird an einem Element ausgelöst, bevor der Browser sein eingebautes Kontextmenü anzeigt. Meist geschieht das per Rechtsklick. Es kann aber auch über die Kontextmenü-Taste der Tastatur, Umschalt+F10 oder langes Drücken auf Touch-Geräten kommen. Das Ereignisobjekt ist ein PointerEvent (in älteren Browsern ein MouseEvent). Es enthält also Koordinaten wie clientX/clientY sowie Zusatztasten wie shiftKey oder ctrlKey.

Ruft man event.preventDefault() auf, zeigt der Browser sein Standardmenü nicht an. So baut man eigene Kontextmenüs, zum Beispiel in Dateimanagern, Editoren, Tabellen oder Spielen. Das Ereignis steigt durch den DOM-Baum auf (Bubbling) und lässt sich abbrechen (cancelable). Deshalb eignet es sich gut für Ereignisdelegation an einem gemeinsamen Elternelement.

Man registriert einen Handler entweder mit addEventListener("contextmenu", handler) oder über die Eigenschaft element.oncontextmenu = handler. Mit addEventListener sind mehrere Handler möglich, die sich mit removeEventListener gezielt wieder entfernen lassen. Die on-Eigenschaft nimmt dagegen immer nur einen Handler auf.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "contextmenu".
$handler Pflicht (event: PointerEvent) => void Callback, der das Ereignisobjekt erhält. Es liefert unter anderem clientX, clientY, pageX, pageY, button (meist 2), target und preventDefault().
$options boolean | AddEventListenerOptions false Optionen wie capture, once, passive oder signal. Achtung: Mit passive: true wirkt preventDefault() nicht.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Gibt man mit preventDefault() das Ereignis ab (bzw. mit return false bei oncontextmenu), erscheint das Standardmenü des Browsers nicht.

Beispiele

Eigenes Kontextmenü an der Mausposition anzeigen

const area = document.querySelector('#arbeitsflaeche');
const menu = document.querySelector('#kontextmenue'); // <ul hidden> mit position: fixed im CSS

area.addEventListener('contextmenu', (event) => {
  event.preventDefault(); // Browser-Menü unterdrücken
  menu.style.left = `${event.clientX}px`;
  menu.style.top = `${event.clientY}px`;
  menu.hidden = false;
});

// Menü bei Klick irgendwo oder Escape schließen
document.addEventListener('click', () => { menu.hidden = true; });
document.addEventListener('keydown', (event) => {
  if (event.key === 'Escape') menu.hidden = true;
});

Ereignisdelegation: Zeile in einer Tabelle erkennen

const table = document.querySelector('#dateien');

table.addEventListener('contextmenu', (event) => {
  const row = event.target.closest('tr[data-id]');
  if (!row) return; // außerhalb einer Zeile: Standardmenü zulassen
  event.preventDefault();
  console.log(`Kontextmenü für Datei ${row.dataset.id} bei (${event.clientX}, ${event.clientY})`);
});
Kontextmenü für Datei 42 bei (318, 205)

Handler wieder entfernen und oncontextmenu-Variante

const canvas = document.querySelector('canvas');

const blockMenu = (event) => event.preventDefault();
canvas.addEventListener('contextmenu', blockMenu);

// Später, z. B. nach Spielende: Standardmenü wieder erlauben
const stopGame = () => {
  canvas.removeEventListener('contextmenu', blockMenu);
  console.log('Kontextmenü wieder aktiv');
};

// Alternative über die on-Eigenschaft (nur ein Handler möglich)
const img = document.querySelector('img.vorschau');
img.oncontextmenu = (event) => {
  event.preventDefault();
  console.log('Rechtsklick auf', img.alt);
};
// Entfernen:
// img.oncontextmenu = null;

stopGame();
Kontextmenü wieder aktiv

Mit AbortController mehrere Listener gleichzeitig abmelden

const controller = new AbortController();
const editor = document.querySelector('#editor');

editor.addEventListener('contextmenu', (event) => {
  event.preventDefault();
  console.log('Editor-Menü');
}, { signal: controller.signal });

// Beim Zerstören der Komponente alle Listener auf einmal entfernen
controller.abort();

// Wichtig · Fallstricke

  • Barrierefreiheit: Wer das Standardmenü unterdrückt, nimmt Nutzern Funktionen wie „Link in neuem Tab öffnen“, „Kopieren“ oder die Rechtschreibprüfung weg. Unterdrücken Sie das Menü nur gezielt. Eigene Menüs sollten per Tastatur bedienbar sein (Pfeiltasten, Escape) und passende ARIA-Rollen tragen (role="menu", role="menuitem").
  • Kein Schutz für Inhalte: Ein blockierter Rechtsklick schützt weder Bilder noch Text. Entwicklerwerkzeuge, der Quelltext und Screenshots bleiben ja verfügbar.
  • Firefox: Hält der Nutzer Umschalt gedrückt, zeigt Firefox trotz preventDefault() das Standardmenü an. Außerdem lässt sich die Option dom.event.contextmenu.enabled abschalten; dann kann eine Seite das Menü gar nicht unterdrücken.
  • Tastatur-Auslösung: Öffnet man das Menü per Taste, können clientX/clientY je nach Browser 0 sein oder auf das fokussierte Element zeigen. Positionieren Sie Ihr Menü in diesem Fall am event.target, zum Beispiel mit getBoundingClientRect().
  • macOS: Strg+Klick löst ebenfalls contextmenu aus, und zwar mit button === 0.
  • Touch-Geräte: Langes Drücken löst das Ereignis auf Android aus, auf iOS Safari teils nicht zuverlässig. Dort braucht man eventuell eine eigene Erkennung für langes Drücken über Pointer-Events.
  • Reihenfolge: Bei einem Rechtsklick kommt meist erst mousedown (button 2), dann contextmenu und dann mouseup. Unter Windows feuert contextmenu erst nach mouseup. Verlassen Sie sich also nicht auf eine feste Reihenfolge.
  • Das Attribut contextmenu und das Element <menu type="context"> sind veraltet und wurden aus allen Browsern entfernt. Verwenden Sie stattdessen dieses Ereignis.