Default-Aktionen des Events verhindern
Javascript kann Aktionen, die durch ein Event ausgelöst werden, auf zweierlei Weise unterbinden:
- Event.preventDefault
- Event.stopPropagation
Einige HTML-Elemente führen Aktionen auch ohne Javascript bei Ereignissen durch. Ein Klick oder Touch auf einen Link führt z.B. zu einer neuen Seite. Ein Formular wird versendet, wenn der Benutzer auf den Button »Absenden« klickt. preventDefault verhindert, dass die vorgesehene Aktion des HTML-Elements durchgeführt wird, z.B., um das Formular mit Javascript zu prüfen, bevor es an die Anwendung auf dem Server geschickt wird.
preventDefault
Typischer Einsatz für evt.preventDefault() sind Formulare, die vor dem Ansenden durch Javascript geprüft werden. Wenn ein Javascript-Event an den submit-Button gebunden ist, muss das normale Verhalten des Buttons unterbunden werden, um das Weiterleiten der Daten an die Anwendung auf dem Server zu blockieren.
elem.addEventListener ('click', function (evt) {
// Ereignis behandeln
evt.preventDefault();
});
- DOM: preventDefault()
- Kann das Ereignis canceln. Verhindert jegliche Browser-Aktion für das Ereignis, etwa das Laden einer URL, wenn ein Link geklickt wurde.
Event stopPropagation
Bei einem Klick auf einem Button entsteht das Event nicht etwa auf dem Button, sondern Events entstehen immer auf dem window-Element und reisen dann durch den DOM-Baum nach unten (»Capturing Phase). Auf dem Weg nach unten informieren sie jedes HTML-Element: »Hi, hier ist ein Klick! Hast du auf mich gewartet?«.
Dann reist das Event in der Bubbling-Phase wieder nach oben bis zum ROOT. evt.stopPropagation verhindert die Weiterreise des Events. Das ist der Unterschied zwischen preventDefault und return false: return false unterbindet auch die Reise des Events nach oben.
preventDefault vs stopPropagation
preventDefault für das erste Bild verhindert die vorgegebene Aktion des a-Elements, so dass die Seite nicht über den Link verlassen wird. Das Event trifft aber dennoch auf dem Weg zurück nach oben den Parent Node und wird hier erkannt.
<div id="logo1"> <a id="thelink1" href="formulare-http.html"> <img src="logo.png" width="" height="" alt=""> </a> </div> <div id="logo2"> <a id="thelink2" href="formulare-http.html"> <img src="logo.png" width="" height="" alt=""> </a> </div>
stopPropagation im zweiten Kasten verhindert die vorgegebene Aktion des a-Elements nicht. Aber sein Parent Node würde nichts mehr davon mitbekommen.
let link1 = document.querySelector('#link1'); link1.onclick = function (evt) { evt.preventDefault(); console.log('Du gehst hier nicht weg!'); } thelink1.parentNode.onclick = function ( evt ) { console.log ('Das habe ich gehört!'); }
let link2 = document.querySelector('#link2'); link2.onclick = function (evt) { evt.stopPropagation(); console.log('Ich mach trotzdem den Abflug!'); } thelink2.parentNode.onclick = function ( evt ) { console.log ('Davon werde ich nie etwas hören!'); }
In den überwiegenden Situationen brauchen wir preventDefault. Man kann aber durchaus beides zusammenbinden:
evt.stopPropagation().preventDefault();