The event.preventDefault() method
event.preventDefault() cancels the default behaviour the browser performs for a given event.
The event still happens and all handlers still run, but the browser will not do its standard action: it will not follow the link, will not submit the form, will not open the context menu.
Theory
TL;DR
- The method switches off the browser's built-in reaction to an event, not the event itself.
- It does not stop propagation: handlers on ancestors still receive the event, that is what
stopPropagation()is for. - It only works for events that have a default action and that can be cancelled (
event.cancelable === true). - The usual cases: form
submit, aclickon a link,contextmenu,dragover, keyboard shortcuts. - After the call
event.defaultPreventedbecomestrue, which the rest of the chain can check.
Quick example
link.addEventListener('click', (event) => {
event.preventDefault(); // no navigation happens
console.log('Link clicked, but there is no navigation');
});Which browser actions count as default
| Element / event | Default browser behaviour |
|---|---|
<a href="..."> + click | following the link |
<form> + submit | sending the form and reloading the page |
<input type="text"> + keypress Enter | may trigger a form submit |
Context menu (contextmenu) | opening the right-click menu |
<input type="checkbox"> + click | toggling the state (checked or unchecked) |
Example 1: cancel link navigation
<a href="https://example.com" id="link">Go</a>
<script>
const link = document.querySelector('#link');
link.addEventListener('click', (event) => {
event.preventDefault(); // cancel the navigation
console.log('Link clicked, but there is no navigation');
});
</script>The message appears in the console, but the page does not navigate to the other site.
Example 2: keep the form from submitting
<form id="login">
<input type="text" name="login" />
<button>Submit</button>
</form>
<script>
const form = document.querySelector('#login');
form.addEventListener('submit', (event) => {
event.preventDefault(); // do not let the form reload the page
console.log('The form was handled manually in JS');
});
</script>This is the basic technique when you want to send the data through JavaScript (fetch, axios) instead of a plain HTML submit.
Example 3: disable the context menu
document.addEventListener('contextmenu', (event) => {
event.preventDefault();
console.log('Context menu disabled');
});Now a right click will not open the browser's standard menu.
Example 4: combined with stopPropagation()
Sometimes you need both to cancel the action and to stop the bubbling:
button.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
console.log('The click was fully intercepted');
});Limits worth remembering
preventDefault()does not stop the event: other handlers, on the same element or above it, still run. To cut everything off you needstopImmediatePropagation().- It only works with events that have a default behaviour. On a
clickon a plaindiv, for instance, it does nothing, because such a click triggers no default action. - If
event.cancelable === false(thescrollevent, for example), the call is simply ignored. - For passive listeners (
{ passive: true }, which is the default fortouchstartandwheelat document level) the browser ignores the call and prints a console warning. To cancel scrolling you must add the listener explicitly with{ passive: false }.
Summary table
| Method | What it does | Example |
|---|---|---|
event.preventDefault() | Cancels the browser's default behaviour | Do not follow the link, do not submit the form |
event.stopPropagation() | Stops the event from bubbling up | Do not pass the event to the parents |
event.stopImmediatePropagation() | Fully stops all remaining handlers | Cut the processing off entirely |
A short mnemonic:
preventDefault()means "do not do the default action",stopPropagation()means "do not carry the event upward".
Common mistakes
- Thinking the method stops the event. It does not: parent handlers still fire, the event's route is unchanged.
- Calling it on an event with no default action and expecting an effect: on a
clickon adivor on a custom event it simply does nothing. - Calling it after an async step. An
await fetch(...)beforepreventDefault()is already too late: the browser decides the fate of the default action synchronously, right after the handler. - Adding
preventDefault()tosubmitbut forgetting validation. Built-in HTML validation runs before thesubmitevent, so the manual checks are now yours to write. - Confusing it with
return false. In a DOM handlerreturn falsecancels nothing; that is jQuery behaviour, where it meanspreventDefault()plusstopPropagation()at once.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.