Web

Why Form Reloads Despite event.preventDefault() Fix

Fix page reload on form submit even with event.preventDefault() on button click. Learn to use form submit event listener, handle Enter key, programmatic submit, and debugging steps for reliable prevention.

1 answer 1 view

Why does the page reload on form submit despite calling event.preventDefault() in JavaScript?

I am trying to prevent a form from reloading the page on submit using event.preventDefault(), but the page still reloads when clicking the submit button.

HTML:

html
<form id="loginForm">
 <input type="text" id="username" />
 <button type="submit" id="submitBtn">Submit</button>
</form>

JavaScript:

javascript
const btn = document.getElementById("submitBtn");
btn.addEventListener("click", function (event) {
 event.preventDefault();
 console.log("Button clicked");
});

The event handler runs (console.log appears), but the page reloads anyway. What is the correct way to prevent form submission and page reload? Why doesn’t this code work as expected?

Calling event.preventDefault() on the submit button’s click often won’t reliably stop the form because the browser still runs the form’s submit flow (or another script calls form.submit()). Use preventDefault on the form’s submit event or change the button to type="button" to stop the page reload. For example: form.addEventListener('submit', e => e.preventDefault()) prevents reload for clicks and Enter-key submits and avoids cases where click handlers don’t catch the real submit.


Contents


Quick fix — preventDefault javascript (correct code)

The simplest reliable fix is to prevent the form’s submit event instead of only the button’s click. That catches any submit trigger (button click, Enter key, or JS-triggered submission) and stops the browser navigation.

Correct approach — listen to submit on the form:

html
<form id="loginForm">
 <input type="text" id="username" />
 <button type="submit" id="submitBtn">Submit</button>
</form>

<script>
const form = document.getElementById('loginForm');
form.addEventListener('submit', function (event) {
 event.preventDefault(); // stops the browser navigation / page reload
 console.log('Form submit prevented — handle data via JS here');
 // do your AJAX / validation here
});
</script>

Alternative: if you only want the button click to run JS and never submit the form, change the button to type="button" and handle its click:

html
<button type="button" id="submitBtn">Submit</button>
<script>
document.getElementById('submitBtn').addEventListener('click', () => {
 // no page reload because button isn't a submit control
});
</script>

The form.addEventListener('submit', ...) approach is the recommended pattern because it covers all submission paths. See the explanation about event ordering and form submit handling on W3Schools and GeeksforGeeks for more context: https://www.w3schools.com/jsref/event_preventdefault.asp and https://www.geeksforgeeks.org/html/how-to-prevent-buttons-from-submitting-forms-in-html/.


Why your code doesn’t work — event preventdefault and submit ordering

You attached preventDefault() to the button’s click event. That prevents the click’s default action for that event object, but it doesn’t guarantee the form’s submit flow will be stopped in every scenario. There are three common reasons the page still reloads:

  • Enter-key submission: Hitting Enter inside a text input often triggers the form’s submit event without firing the button’s click handler first. So your click listener never runs for that submit path.
  • Programmatic submission: Another script can call form.submit() directly. Programmatic submission does not necessarily go through the same cancelable submit event flow, so your click handler can’t stop it.
  • Other handlers or ordering: There may be other listeners (or inline onsubmit) that run after your click handler and either submit, return a truthy value, or call form.submit().

W3Schools points out that the submit event is the right place to call preventDefault(), and that preventing the click alone can be unreliable in practice: https://www.w3schools.com/jsref/event_preventdefault.asp. StackOverflow threads and community answers make the same point: attach the handler to the form’s submit event or use type="button" for non-submitting buttons (examples: https://stackoverflow.com/questions/3350247/how-to-prevent-form-from-being-submitted, https://stackoverflow.com/questions/59201401/how-does-preventdefault-and-type-submit-work-with-forms).

A short rule of thumb: prevent the submit event, not just the click.


Common edge cases: programmatic form.submit(), Enter key, other handlers

  1. Programmatic submission (form.submit()):
  • If some code calls myForm.submit() directly, that may bypass the usual submit-event cancellation. The HTML standard and browser behaviour mean programmatic submit can skip the submit event or behave differently, so event.preventDefault() on a click won’t stop that.
  • Detection tip (temporary, for debugging): monkey-patch HTMLFormElement.prototype.submit to log a stack trace so you can find who’s calling it:
javascript
const nativeSubmit = HTMLFormElement.prototype.submit;
HTMLFormElement.prototype.submit = function() {
console.warn('programmatic submit called on', this);
console.trace();
return nativeSubmit.apply(this, arguments);
};

Don’t leave this in production.

  1. Enter key in inputs:
  • Pressing Enter inside a text input triggers form submit without a button click; your button click handler won’t run. Listening for the form’s submit fixes this.
  1. Multiple handlers & propagation:
  • event.preventDefault() stops the default action for that specific event. If another listener later calls form.submit() the navigation can still happen. If you need to block other listeners attached to the same event, e.stopImmediatePropagation() inside a submit handler will prevent other listeners on that event from running — but it still won’t stop a direct form.submit() call.
  1. Passive listeners:
  • If an event listener was registered with { passive: true }, preventDefault() inside it is ignored. That usually applies to touch/wheel listeners, but it’s worth checking if someone used passive options incorrectly.

StackOverflow threads discuss these failure modes and offer practical fixes: https://stackoverflow.com/questions/23284793/why-does-preventdefault-of-a-click-event-also-prevent-my-form-from-submitting and https://stackoverflow.com/questions/15051128/prevent-form-from-submitting-via-event-preventdefault-not-working.


Debugging steps to find what triggers the reload

If calling event.preventDefault() in your click handler logged but the page still reloads, try this checklist to find the real submit trigger:

  • Attach a submit listener that logs and traces the stack:
javascript
form.addEventListener('submit', function(e) {
console.log('submit event fired');
console.trace();
e.preventDefault(); // keep page from reloading while debugging
});

This shows whether the submit event fires and gives a stack trace.

  • Monkey-patch HTMLFormElement.prototype.submit (shown above) to detect programmatic submissions.

  • Search your codebase for .submit(, onsubmit=, or addEventListener('submit' to find other submit logic.

  • Use DevTools Event Listener Breakpoints: open Chrome/Edge DevTools → Sources → Event Listener Breakpoints → expand “DOM” or “Control” and enable “submit” and/or “click”. Reload and trigger the behavior; the debugger will pause where the event or handler runs.

  • Check for frameworks/plugins: UI libraries or form libraries might auto-submit or use AJAX. Disable them temporarily to isolate the issue.

  • Confirm listener attachment timing: ensure your script runs after the DOM is ready so the listener is actually attached. If you see console.log it’s attached, but still check ordering relative to other scripts.

These steps usually reveal whether the submit comes from a browser action, a user pressing Enter, or another script.


Best practices and robust examples (AJAX, disable double-submit)

Use the form submit listener as your canonical single place to handle submission, validation, and AJAX. Keep UX and accessibility in mind: keyboards should still work; screen readers expect forms to behave predictably.

Example: AJAX submit with prevention and button-disable to avoid double-posts:

html
<form id="loginForm" action="/login" method="post">
 <input name="username" id="username" required />
 <button type="submit" id="submitBtn">Log in</button>
</form>

<script>
const form = document.getElementById('loginForm');
const btn = document.getElementById('submitBtn');

form.addEventListener('submit', async function (e) {
 e.preventDefault(); // stop page reload
 btn.disabled = true; // avoid double submissions

 const formData = new FormData(form);
 try {
 const resp = await fetch(form.action, {
 method: form.method,
 body: formData,
 credentials: 'same-origin'
 });
 if (!resp.ok) throw new Error('Server error');
 const data = await resp.json();
 // handle success (redirect manually if needed)
 console.log('Server response:', data);
 } catch (err) {
 console.error(err);
 // show error to user
 } finally {
 btn.disabled = false;
 }
});
</script>

Notes:

  • Keep type="submit" on the button when you want the form to be submittable by keyboard (Enter). If you truly never want the form submitted by that button, use type="button".
  • If you need to block other libraries that might auto-submit, either integrate with those libraries’ hooks or locate/remove the automatic submit logic.
  • When debugging, temporarily call e.preventDefault() at the top of your submit handler so the page won’t navigate while you inspect.

For background reading on using preventDefault() correctly in form flows see GeeksforGeeks and the StackOverflow discussions: https://www.geeksforgeeks.org/html/how-to-prevent-buttons-from-submitting-forms-in-html/ and https://stackoverflow.com/questions/3350247/how-to-prevent-form-from-being-submitted.


Sources


Conclusion

Put preventDefault on the form’s submit event (or change the button to type="button") to reliably stop the page reload. Listening to the form covers clicks, Enter-key submissions, and avoids many pitfalls where preventDefault() on the button click alone doesn’t stop navigation — especially when other scripts or programmatic form.submit() calls are involved.

Authors
Verified by moderation
Moderation
Why Form Reloads Despite event.preventDefault() Fix