Links used to activate JavaScript functions
By Flavio Copes
Prefer a button and addEventListener when you need a click to run JavaScript. The old href="#" and javascript:void(0) patterns are code smells.
When you are creating an app using plain JavaScript, sometimes you’ll have the necessity of triggering a function when the user clicks something.
Suppose the function you want to execute is called handleClick():
function handleClick() {
alert('clicked')
}
What people used to do
For years, people used an <a> tag with either href="#" or href="javascript:void(0)", plus an onclick attribute:
<a href="#" onclick="handleClick()">Click here</a>
<a href="javascript:void(0)" onclick="handleClick()">Click here</a>
With href="#", the browser follows the link and scrolls to the top of the page. To stop that, the onclick attribute itself must return false, like onclick="handleClick(); return false". Returning false from inside handleClick() is not enough, because the attribute discards that value. With javascript:void(0), the scroll does not happen, so many tutorials preferred it.
Both are code smells now. Inline onclick attributes fight Content Security Policy. javascript: URLs are a bad habit. And a link that does not go anywhere is the wrong element for a click action.
Prefer a button and addEventListener
If the click runs a script and does not navigate, use a button:
<button type="button" id="action">Click here</button>
document.querySelector('#action').addEventListener('click', handleClick)
That keeps the handler in your DOM script, not in the markup. It is easier to reuse, and it does not pretend to be a link.
If the element really is a link to another page, keep a real URL in href. Then call event.preventDefault() only when JavaScript takes over:
<a href="/fallback/" id="action">Click here</a>
document.querySelector('#action').addEventListener('click', (event) => {
event.preventDefault()
handleClick()
})
If JavaScript fails to load, the user still gets the fallback page. That is the progressive enhancement path, and it beats javascript:void(0) every time.
Want me to talk about your product? You can sponsor this site.
Related posts about js: