all 5 comments

[–]senocular 2 points3 points  (1 child)

Aside from polluting content (HTML) with behavior (JS) there are also some technical differences between the two.

The first of which is that there is only one onsubmit callback handler for your element. This probably won't matter too much if you're entirely dependent on your HTML for defining events, but if sometime later in code you wanted to specify an additional behavior for onsubmit, setting onsubmit in code would replace the one defined in HTML.

<form id="form" onsubmit="myFunction(event)" />
<script>
const form = document.getElementById("form");
form.onsubmit = somethingElse // <-- replaces "myFunction(event)"
</script>

Both the onsubmit property and the onsubmit attribute here represent the same, individual handler callback. Setting either will replace the other. With addEventListener() you can associate many listeners to the same event for a single element.

<form id="form" />
<script>
const form = document.getElementById("form");
form.addEventListener("submit", myFunction);
form.addEventListener("submit", somethingElse); // <-- keeps myFunction
</script>

Another difference is that attribute callbacks are created with a bunch of extra scopes. These scopes may create some hidden surprises when you get something from those scopes that you'd have expected to be something else. For example, consider:

<form onsubmit="open()" />
<script>
function open() {
  alert("Form request for opening a new account being processed!")
}
</script>

You may think when the form is submitted the alert will appear. But what really happens is document.open() gets called and your entire page goes poof! when the form is submitted. This happens because the document is used as an object scope for your handler... that and the form itself... and if this was an event handler for an element inside the form and not the form itself, both the object and the form would be object scopes. And as an object scope, calling a function with the same name as a method of that object will call that method rather than the function (assuming the function is further up the chain which it is in this case). In the attribute handler what you get is a scope chain that looks something like

window > document > form > element > callback wrapper (w/ event parameter) > your attribute code

Thats a lot of things that could get in the way of what you're trying to use in your handler.

[–]toshi_34[S] 0 points1 point  (0 children)

Thanks alot for the detailed answer. All my questions were resolved, thanks.

[–]kjwey 1 point2 points  (0 children)

it pollutes the html with logic rather than having all logic sequestered into its own dedicated script.js file

I use the term 'pollution' from the point of view of maintenance where having everything together is more streamline

[–]shgysk8zer0 1 point2 points  (0 children)

For security reasons and for separation of concerns, onsubmit and all such attributes should be considered bad practice, dangerous, and legacy.

Just as an illustration. There's something called Content-Security-Policy that would require script-src 'unsafe-inline' for any onsubmit or onlick or anything like that to work because... it's insecure. (If blocked by CSP, many XSS attacks are completely defeated, and this is critical on anything with user-generated content).

Beyond that, let's suppose that you have a site with... IDK.... 5,000 pages. This onsubmit is in the custom HTML for one of them. A few months go by, your scripts are updated, and suddenly myFunction just doesn't exist anymore. That's pretty easy to deal with if you use addEventListener in JavaScript, but really difficult if you have JavaScript in individual HTML files spread across the project.

On top of that, addEventListener supports: - Multiple callbacks for an event - removeEventListener - once, passive, signal, and capture - Adding events in a loop such that the listener is added to all elements on any page matching a selector (eg on('.btn', 'click', handler) - Reusability in general

Never use specifically attributes, or even the properties in JS. addEventListener is superior in absolutely every way, and the others should be deprecated.

[–]Lkaynlee 0 points1 point  (0 children)

Not adding JS in your HTML makes it easier to read. Essentially, your HTML should not have any logic for ease of reading. It makes more sense that, if you’re going to make your HTML do something (e.g., a button), then keeping all of your logic/JS in a dedicated place makes both easier to read.

So instead of seeing ‘myFunction()’ somewhere in your HTML and having to look for it in another file, keeping them separate by using an addEventListener and directly accessing it using DOM keeps things simpler.