What does preventDefault() do?
The Short Answer
preventDefault() stops the browser's default behavior for an event without stopping the event from propagating through the DOM. When you click a link, the browser navigates. When you submit a form, the browser reloads the page. preventDefault() cancels that built-in action while still letting your JavaScript handle the event however you want.
How It Works
Every DOM event has a defaultPrevented property and a cancelable property. When you call preventDefault() on a cancelable event, the browser skips its built-in response. The event still fires, your handlers still run, and the event still bubbles — only the browser's automatic behavior is suppressed.
// Prevent a link from navigating
const link = document.querySelector('a');
link?.addEventListener('click', (event) => {
event.preventDefault();
// Link click fires, but browser doesn't navigate
console.log('Clicked, but staying on this page');
console.log(event.defaultPrevented); // true
});
// Prevent form submission (page reload)
const form = document.querySelector('form');
form?.addEventListener('submit', (event) => {
event.preventDefault();
// Form submit fires, but browser doesn't reload
const data = new FormData(form);
fetch('/api/submit', { method: 'POST', body: data });
});
// Check if an event is cancelable before preventing
document.addEventListener('scroll', (event) => {
console.log(event.cancelable); // false — scroll can't be prevented this way
});
Notice that preventDefault() only works on cancelable events. Some events like scroll on the document aren't cancelable — calling preventDefault() on them does nothing. You can check event.cancelable before calling it.
Common Use Cases
Almost every interactive web app uses preventDefault() somewhere. Here are the most frequent scenarios where you need to override the browser's default behavior.
- Form submission
- Prevent page reload, handle with fetch/AJAX instead
- Link clicks
- Prevent navigation, handle with client-side routing
- Keyboard shortcuts
- Prevent browser shortcuts (Ctrl+S) to implement custom save
- Drag and drop
- Prevent default drag behavior to implement custom DnD
- Context menu
- Prevent right-click menu to show a custom menu
- Input validation
- Prevent form submission when validation fails
preventDefault() vs stopPropagation()
These two methods are often confused but do completely different things. preventDefault() stops the browser's default action. stopPropagation() stops the event from bubbling up to parent elements. They're independent — you can use one, both, or neither.
| preventDefault() | stopPropagation() | |
|---|---|---|
| What it stops | Browser's default behavior | Event bubbling to parent elements |
| Event still fires? | Yes | Yes (on current element) |
| Parent handlers run? | Yes | No |
| Example | Link doesn't navigate | Parent click handler doesn't fire |
| Use together? | Yes — they're independent | Yes — they're independent |
This example shows both methods in action. The inner button prevents the form from submitting (default behavior) and also stops the click from reaching the outer div's handler.
// <div id="outer">
// <form id="myForm">
// <button type="submit">Submit</button>
// </form>
// </div>
document.getElementById('outer')?.addEventListener('click', () => {
console.log('Outer div clicked'); // Won't fire if stopPropagation is called
});
document.getElementById('myForm')?.addEventListener('submit', (event) => {
event.preventDefault(); // Form won't reload the page
event.stopPropagation(); // Click won't reach the outer div
console.log('Form handled via JS');
});
In React
React uses synthetic events that wrap native events, but preventDefault() works the same way. The most common pattern is preventing form submission to handle it with your own logic. React's synthetic event delegates to the native preventDefault() under the hood.
function LoginForm() {
const [email, setEmail] = useState('');
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault(); // No page reload
// Handle submission with your own logic
loginUser(email);
}
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<button type="submit">Log in</button>
</form>
);
}
Don't return false in React
In vanilla JS, returning false from an inline handler (like <a onclick="return false">) prevents the default. In React, this doesn't work — you must explicitly call event.preventDefault().
Why Interviewers Ask This
This question tests your understanding of the browser's event model and how JavaScript interacts with built-in browser behaviors. Interviewers want to see that you know the difference between preventing default behavior and stopping propagation, can name real scenarios where you'd use it, and understand that it only works on cancelable events. It's a foundational DOM concept that every frontend developer uses daily.
Quick Revision Cheat Sheet
What it does: Cancels the browser's built-in response to an event
Event still fires?: Yes — only the default action is suppressed
Still bubbles?: Yes — use stopPropagation() separately to stop bubbling
Cancelable check: event.cancelable tells you if preventDefault() will work
React: Must call explicitly — returning false doesn't work
Common uses: Form submit, link clicks, keyboard shortcuts, drag-and-drop