Void(0) in JavaScript: Was es tut, wann es schadet und wie du es heute besser machst

Du siehst in Code-Reviews noch javascript:void(0) und fragst dich, ob das okay ist? Kurz gesagt: Void(0) ist eine alte, praktische Krücke, um Navigation zu verhindern – heute gibt es dafür saubere, semantische und barrierefreie Alternativen. In diesem Artikel zeige ich dir präzise, was Void(0) macht, woher es kommt, warum es in modernen Projekten selten sinnvoll ist und wie du es sicher ersetzt.

Was ist Void(0) wirklich?

Void ist ein unärer Operator in JavaScript. Er wertet einen Ausdruck aus und gibt immer undefined zurück. Das Standardmuster void(0) oder kürzer void 0 liefert also garantiert undefined – unabhängig davon, welcher Operand verwendet wird.

  • Syntax: void expression (Klammern optional, nur zur Lesbarkeit)
  • Rückgabewert: immer undefined
  • Konvention: void(0) bzw. void 0 für einen minimalen, nebenwirkungslosen Ausdruck

Warum ist das interessant? Weil es in Links (<a href="...">) mit dem Pseudoprotokoll javascript: dazu führt, dass der Browser nicht navigiert und keine neue Seite rendert.

Variante Ergebnis Wann verwenden? Hinweis
void(0) undefined Historisch in href="javascript:..." Verhindert, dass ein Rückgabewert eine Navigation triggert
void 0 undefined Minifizierte/kompakte Schreibweise Funktional identisch zu void(0)
undefined Primitiver Wert Allgemeine JS-Programmierung Seit ES5 global schreibgeschützt; früher überschreibbar

Wie Browser javascript:-URIs verarbeiten

Setzt du das href eines Links auf javascript:…, führt der Browser den JavaScript-Ausdruck aus. Der Rückgabewert kann – je nach Browser – zur Darstellung genutzt werden. Ist er undefined, passiert in der Regel keine Navigation und die bestehende Seite bleibt bestehen. Genau hier kommt Void(0) ins Spiel: Es garantiert undefined.

<a href="javascript:void(0)" onclick="doSomething()">Klicke mich (navigiert nicht)</a>

Merke: javascript:-URIs sind nicht standardkonform im Sinne moderner Best Practices, oft durch Content-Security-Policies blockiert und schlecht für Barrierefreiheit und SEO. Nutze sie heute nur in sehr speziellen Fällen (z. B. Bookmarklets).

Void(0)

Typische Anwendungsfälle – früher vs. heute

Historisch sahst du javascript:void(0) überall dort, wo Links eigentlich nur Aktionen (kein Navigationsziel) auslösen sollten:

  • Platzhalter-Links in frühen Prototypen
  • Mega-Menüs, bei denen der oberste Menüpunkt nur ein Container ist
  • AJAX-Interaktionen vor dem SPA-Zeitalter
  • Bookmarklets, die absichtlich JavaScript ausführen

In modernen Anwendungen verwendest du für Aktionen stattdessen Buttons oder echte Links mit event.preventDefault() – semantisch korrekt, barrierearm und wartbar.

Warum Void(0) heute selten eine gute Idee ist

  • Semantik: Ein <a> ist ein Link. Wenn er nicht navigiert, ist er eigentlich ein Button. Diese Verwechslung schadet der Codequalität.
  • Barrierefreiheit: Screenreader kündigen Links als „Link“ an. Ein Link, der eine Aktion ausführt, bricht Erwartungen und frustriert Nutzer mit Hilfstechniken.
  • SEO: Suchmaschinen folgen javascript:-URIs nicht wie normalen Links. Das verwässert die interne Verlinkung und verschenkt Signale.
  • Sicherheit/CSP: Moderne Content Security Policies blockieren oft javascript:-URIs. Dein UI kann dadurch einfach „kaputt“ wirken.
  • Wartbarkeit: Inline-JS in Attributen (onclick, href="javascript:…") erschwert Trennung von Struktur, Verhalten und Styling.

Moderne Alternativen mit sauberer Semantik

1) Buttons für Aktionen (empfohlen)

Wenn keine Navigation stattfindet, nutze einen <button type="button">. Das Element hat per Default korrekte Tastatur- und Screenreader-Semantik.

<button type="button" id="openModal">Modal öffnen</button>

<script>
  document.getElementById('openModal').addEventListener('click', () => {
    openModal();
  });
</script>
  • Vorteile: Korrekte Semantik, gute A11y, kein Hack nötig
  • Styling-Tipp: Du kannst Buttons wie Links stylen, falls gewünscht

2) Links mit event.preventDefault()

Wenn ein Link aus Designgründen als Link bleiben soll, verhindere die Standardaktion per Event-Listener. So bleibt er fokussierbar und klickbar – aber du steuert das Verhalten.

<a href="#" id="toggleDetails">Details anzeigen</a>

<script>
  const link = document.getElementById('toggleDetails');
  link.addEventListener('click', (e) => {
    e.preventDefault(); // verhindert das Springen zu "#"
    toggleDetails();
  });
</script>

Wichtig: href="#" scrollt ohne preventDefault() an den Seitenanfang. Deshalb immer das Event sauber verhindern. Besser noch: Gib echte Navigationsziele an, wenn verfügbar.

3) Progressive Enhancement mit echter Fallback-URL

Ideal ist eine echte URL im href, die serverseitig dieselbe Aktion (oder eine sinnvolle Alternative) bereitstellt. JavaScript macht es nur „schöner“ und schneller.

<a href="/account/delete" id="deleteAccount">Account löschen</a>

<script>
  document.getElementById('deleteAccount').addEventListener('click', async (e) => {
    e.preventDefault();
    if (confirm('Wirklich löschen?')) {
      await deleteAccountViaAPI();
      location.href = '/goodbye';
    }
  });
</script>

4) Kein return false als Allzweckwaffe

Achtung: In addEventListener-Handlern bewirkt return false nichts. Es funktioniert nur in Inline-Handlern (z. B. onclick="return false") oder abstrahierend in jQuery. Nutze in Vanilla-JS konsequent event.preventDefault() und bei Bedarf event.stopPropagation().

Void(0)

Vergleich: Optionen für „klicke, aber navigiere nicht“

Methode Syntax-Beispiel Semantik Barrierefreiheit SEO CSP/Policy Empfehlung
javascript:void(0) <a href="javascript:void(0)">...</a> Link ohne Ziel Probleme (erwartetes Linkverhalten fehlt) Kein Linksignal Oft blockiert Nicht nutzen (außer Bookmarklets)
href="#" + preventDefault() link.addEventListener('click', e => e.preventDefault()) Link-Feeling, keine Navigation Okay, aber semantisch grenzwertig Kein echtes Ziel Unkritisch Akzeptabel, wenn Link-Optik nötig
<button type="button"> <button>Aktion</button> Korrekte Aktion Gut (Tastatur, Screenreader) N/A Unkritisch Empfohlen für Aktionen
Echte URL + JS-Enhancement <a href="/ziel">...</a> Navigation mit Progressive Enhancement Gut Volle Linksignale Unkritisch Best Practice für Navigationsaktionen

Void im modernen JS: IIFEs elegant absichern

Abseits von Links hat Void einen legitimen, gelegentlich nützlichen Einsatz: bei Immediately Invoked Function Expressions (IIFEs). Du kannst mit void erzwingen, dass eine Funktionsdefinition als Ausdruck geparst wird – und zugleich ihren Rückgabewert verwerfen:

// Klassisch:
(function () {
  console.log('IIFE ausgeführt');
})();

// Mit void:
void function () {
  console.log('IIFE ausgeführt, Rückgabewert verworfen');
}();

Warum funktioniert das? Der Funktionsaufruf hat höhere Auswertungspriorität als der unäre Operator. Der Aufruf passiert zuerst, der Rückgabewert wird durch void zu undefined „gemacht“. Das ist ein legitimer, sauberer Trick – und semantisch klarer als manch anderer Workaround.

Hinweis: Bei Arrow Functions brauchst du weiterhin Klammern, z. B. (() => {...})(). Das void-Muster richtet sich v. a. an klassische Function-Expressions.

Debugging: Wenn Klicks „nichts tun“ und du javascript:void(0) siehst

Du hoverst über einen Link, die Statusleiste zeigt javascript:void(0) und ein Klick tut nichts? Das ist meist Absicht – aber wenn eigentlich etwas passieren sollte, prüfe Folgendes:

  • Konsole prüfen: Öffne DevTools, sieh dir Fehlermeldungen an (Syntaxfehler, Referenzfehler, CSP-Verstöße).
  • JavaScript aktiv? Deaktiviertes JS oder strikte Browser/Enterprise-Policies verhindern Ausführung.
  • Extensions/Blocker: Script-Blocker, Ad-Blocker, Tracking-Protection, ITP oder NoScript können Handlers blockieren.
  • Content Security Policy: Prüfe, ob javascript:-URIs oder Inline-Handler durch CSP verboten sind.
  • Event-Bindung: Ist der Listener wirklich registriert? Event-Delegation korrekt? Tippfehler bei Selektoren?
  • Propagation: Verhindert stopPropagation()/stopImmediatePropagation() andere Handler?
  • Netzwerkfehler: Bei AJAX-Calls: CORS, 401/403/500, Mixed Content, Preflight-Fehler überprüfen.

Praxis-Tipp: Ersetze schrittweise href="javascript:void(0)" durch Buttons oder Links mit echter URL plus preventDefault(). Achte auf konsistente Semantik und klare Fallbacks.

Sicherheit und Policies: Warum javascript: oft blockiert wird

Viele Organisationen setzen restriktive Content Security Policies (CSP) ein. javascript:-URIs zählen zur Kategorie „Inline-Skript“. Fehlt 'unsafe-inline' in script-src, werden solche Aufrufe blockiert. Zudem verhindern manche Browser/Extensions gezielt das Navigieren zu javascript:-URIs. Setzt du auf Void(0), riskierst du daher eine fragile UI.

Barrierefreiheit: Vermeide semantische Fallen

Ein Link ist ein Link. Ein Button ist ein Button. Diese Einfachheit sorgt für zuverlässige Bedienung mit Screenreadern, Tastatur und Sprachsteuerung. Breche diese Erwartungen nicht:

  • Für Aktionen: <button type="button"> nutzen, nicht <a>.
  • Disclosure/Accordions: <button aria-expanded="false" aria-controls="panel-1"> statt Link-Hacks.
  • Keyboard: Buttons können Enter und Space; Links typischerweise nur Enter.
  • Kontextmenü: „In neuem Tab öffnen“ auf einem Pseudo-Link ohne Ziel ist irreführend.
<button
  type="button"
  aria-expanded="false"
  aria-controls="filter-panel"
  id="filterToggle">
  Filter anzeigen
</button>

<div id="filter-panel" hidden>...</div>

<script>
  const btn = document.getElementById('filterToggle');
  const panel = document.getElementById('filter-panel');

  btn.addEventListener('click', () => {
    const expanded = btn.getAttribute('aria-expanded') === 'true';
    btn.setAttribute('aria-expanded', String(!expanded));
    panel.hidden = expanded;
  });
</script>

SEO und Analytics: Linksignale korrekt setzen

javascript:-URIs liefern keine klassischen Linksignale. Wenn du Navigation oder wichtige interne Verlinkung über solche Links abbildest, fehlen Crawlern Signale zu Relevanz, Struktur und Priorität. Nutze echte hrefs für Navigation, auch wenn du clientseitig aufwärtest.

  • Interne Verlinkung: Echte URLs im href mit semantischem Linktext.
  • Clientseitig: SPA-Router sollten URLs pushen (history.pushState) und serverseitig Fallbacks anbieten.
  • Tracking: Klicktracking zuverlässig über Event-Listener statt javascript:-Hacks.

Performance und Wartbarkeit

Von Inline-Events (onclick="…", href="javascript:…") solltest du aus Gründen der Wartbarkeit und Testbarkeit Abstand nehmen:

  • Trennung der Belange: HTML (Struktur), CSS (Präsentation), JS (Verhalten) getrennt halten.
  • Event-Delegation: Weniger Listener, weniger Memory-Footprint, einfachere Dynamik.
  • Testing: Modul- und Integrationstests profitieren von klaren, testbaren Funktionen.
document.addEventListener('click', (e) => {
  const btn = e.target.closest('[data-action]');
  if (!btn) return;

  switch (btn.dataset.action) {
    case 'open-modal':
      openModal();
      e.preventDefault(); // falls Link-Optik
      break;
    // ...
  }
});

Edge Cases: Wann Void(0) noch okay ist

  • Bookmarklets: Nutzer speichern javascript:-Snippets als Lesezeichen. void(0) verhindert ungewollte Seitennavigation.
  • Spezielle Debug-Workflows: Schnell mal Inline-Code testen (besser: DevTools-Snippets).
  • IIFEs mit void: Siehe oben – stilistisch vertretbar.

Grundregel: Für UI-Interaktion im DOM: Keine href="javascript:…" verwenden. Verwende Buttons oder echte Links plus JS.

Cheatsheet: Do’s and Don’ts

  • Do: Nutze <button type="button"> für rein aktionale Interaktionen.
  • Do: Verwende event.preventDefault() für Links, wenn du bewusst die Navigation verhinderst.
  • Do: Liefere echte href-Ziele für Navigation und SEO.
  • Don’t: Kein href="javascript:void(0)" in modernen UIs.
  • Don’t: Keine Inline-Handler; stattdessen addEventListener.
  • Don’t: Kein return false in addEventListener-Handlern erwarten.

Praxisbeispiele: Vorher/Nachher

Vorher (Legacy):

<a href="javascript:void(0)" onclick="saveForm()">Speichern</a>

Nachher (besser):

<button type="button" id="saveBtn">Speichern</button>

<script>
  document.getElementById('saveBtn').addEventListener('click', async () => {
    const ok = await saveForm();
    if (ok) notify('Gespeichert');
  });
</script>

Vorher (Pseudo-Link öffnet Panel):

<a href="javascript:void(0)" onclick="togglePanel()">Panel</a>

Nachher (barrierearm):

<button type="button" aria-expanded="false" aria-controls="panel">Panel</button>
<div id="panel" hidden>...</div>

Feinheiten rund um undefined, null und void

  • undefined: Ein primitiver Wert. Bedeutet „nicht zugewiesen“. Seit ES5 global schreibgeschützt.
  • null: Ein primitiver Wert, der „absichtlich leer“ bedeutet (typisch wenn ein Objekt erwartet wäre).
  • void: Ein Operator, der das Ergebnis auswertet und undefined zurückgibt (z. B. void 0).

Historisch nutzten Entwickler void 0, um den echten undefined-Wert sicher zu erhalten, falls die Variable undefined (vor ES5 möglich) überschrieben wurde. Heute ist das meist nicht mehr nötig – aber der Operator bleibt ein valides Sprachfeature.

Fazit

Void(0) ist ein Teil der JavaScript-Geschichte – hilfreich in einer Zeit, in der wir Interaktionen ohne Page Reload hacken mussten. Heute weißt du es besser: Für Aktionen nutzt du Buttons, für Navigation echte Links mit sinnvollen URLs. Wenn du die Standardaktion verhindern möchtest, greifst du zu event.preventDefault() und hältst JavaScript sauber in Event-Listenern, fernab von Inline-Attributen. So gewinnst du Semantik, Barrierefreiheit, SEO, Sicherheit und Wartbarkeit. Nutze Void(0) nur dort, wo es wirklich hingehört: in Bookmarklets, Tests oder als eleganter IIFE-Kniff – nicht als UI-Standard.

FAQ

Was macht Void(0) genau?
Der Operator void wertet einen Ausdruck aus und gibt immer undefined zurück. In href="javascript:void(0)" verhindert das eine Navigation/Seitenersetzung.

Ist Void(0) und void 0 dasselbe?
Ja. void(0) und void 0 sind funktional identisch. Klammern dienen nur der Lesbarkeit.

Warum sollte ich href="javascript:void(0)" vermeiden?
Wegen schlechter Semantik, Barrierefreiheitsproblemen, fehlenden SEO-Signalen und möglichen CSP-Blockaden. Besser: Button für Aktionen; echte Links für Navigation.

Reicht href="#" als Ersatz?
Nur, wenn du event.preventDefault() im Klick-Handler nutzt. Andernfalls springt die Seite nach oben. Semantisch ist ein Button meist die bessere Wahl, wenn keine Navigation stattfindet.

Was ist mit return false?
In addEventListener-Handlern hat return false keine Wirkung. Verwende event.preventDefault() (und optional stopPropagation()). In Inline-Handlern oder jQuery verhält es sich anders.

Wie ersetze ich einen Pseudo-Link sauber?
Wenn er eine Aktion ausführt: durch <button type="button">. Wenn er navigiert: bleib bei <a href="echte-url"> und optimiere Interaktionen clientseitig.

Kann ich Void sinnvoll nutzen?
Ja, z. B. als IIFE-Kniff: void function(){ ... }(). Für UI-Interaktionen im DOM solltest du href="javascript:..." jedoch meiden.

Warum sehe ich javascript:void(0) in der Statusleiste?
Weil der Link genau dieses href hat. Wenn nichts passiert, kann das Absicht sein – oder JS/CSP/Extensions verhindern die Ausführung. Prüfe die DevTools-Konsole.

Beeinflusst javascript: die SEO?
Ja. Suchmaschinen werten solche „Links“ in der Regel nicht als echte Verlinkung. Das schwächt interne Linksignale. Nutze echte URLs.

Was ist mit CSP und Sicherheit?
Strenge CSPs blockieren javascript:-URIs und Inline-Skripte. Verlasse dich deshalb nicht auf href="javascript:void(0)"; nutze Ereignislistener und getrennte Skriptdateien.

Kommentar abschicken