Yes, I am saying that you should never use <a href="javascript:void 0"> or similar. (<a href="#"> is illegitimate in most cases, but is occasionally used honestly to cause scrolling to the top of the page.)
Buttons aren't perfect, either, you have to write additional code to handle middle-click actions, and the right-click menu doesn't contain the expected "Open in New Tab" or "Copy Link Location".
I prefer to use buttons to affect the state of the current page. And use anchor tags for all other navigation, even if I'm handling it with .addEventListener("click", ...).
I suppose I could just hide the non-functional links, or add them dynamically with javascript. But that could affect layout.
Still, your solution is nicer in many ways, thanks.
But yeah, stylesheets might need adjustment for best results if you want to keep it on-screen even when it’s not operative, e.g. add a class link-needs-js which you style along with your :link, :visited.
In the hidden versus disabled thing, I do approximately this, if I have functionality that can’t work without JS (for whatever reason): if it’s completely optional, I hide it; if it’s important, I show it with a disabled style including not-allowed cursor (the disabled attribute if it’s a button, or a class if it’s an anchor) and some kind of “JS required” title, to at least give a hint as to why it’s not working and what the user must to do make it work. Anything between those extremes, I decide on a case-by-case basis, being influenced also by what else is there and does work.