Using the "Good Parts" defaults on JSLint, the use of HTML event handlers (such as onclick) is not allowed.
What is the logic behind this? What is bad about them that should be avoided?
Using the "Good Parts" defaults on JSLint, the use of HTML event handlers (such as onclick) is not allowed.
What is the logic behind this? What is bad about them that should be avoided?
I think the reason is this:
When you use a default event handler, there can only be one registered function.
There might be one defined already (via the onclick
attribute), and when you re-define it in JS code, the original handler gets lost, possibly breaking functionality. This cannot happen if you take the "add event handler" route (for example via jQuery's bind()
).
For a small web app that you control completely, this might be okay. If the JS code you are writing is a plugin/library of some sort, this behavior becomes unacceptable.
The logic is best summed up by the phrase "separation of concerns", which is a common tenet of software engineering. In this case, having an inline event handler in the HTML is bringing a behavioral concern (event handler) into your presentation concern (HTML). For some ancient advice, see Unobtrusive DHTML, and the power of unordered lists. Other good sources are A List Apart and of course Wikipedia.
Nothing's wrong with them. However, you can only attach one listener via that method (as opposed to using addEventListener
/ attachEvent
, which allow multiple listeners). This may not be a problem for a simple application, however.
The other issue is that if you're using event handler attributes in your HTML, you are mixing content with behaviour. This is not ideal and the unobtrusive JavaScript crowd will tut at you for doing it, but again, achieving this separation is not the only consideration and for a very simple application I'd favour this method for its simplicity. There is also a feature of event handler attributes that no other mechanism has, which is that the JavaScript behaviour is available immediately after the element is rendered rather than once the document has loaded (the typical time you would otherwise assign an event handler).
Using the "Good Parts" defaults on JSLint, the use of HTML event handlers (such as onclick) is not allowed.
The use of event handlers in the actual markup is flagged, yes:
<div onclick="...">
This is generally considered bad practice. Mixing scripting behaviour into markup is hard to read and manage; easier to keep all your scripting together, in an actual script, so you don't have to delve into your markup to find what scripting hooks are being called.
Also, by putting your script code in a context where it needs HTML-encoding, you are adding an extra layer of escaping confusion. You end up saying nasty stuff like:
<div onclick="if (a<b) this.innerHTML= "I said \"Hello &amp; welcome!\""">
naturally it's difficult to get this encoding right, and if you're dealing with dynamic values an incorrect combination of encodings leaves you with a script-injection (XSS) problem.
The same in a standalone script:
somediv.onclick= function() {
if (a<b)
this.innerHTML= "I said \"Hello & welcome!\"";
};
is one escaping level clearer.
JSLint does not complain about this usage. Whilst some would argue that using listeners is better as you can add multiple listeners to an event, that's more of a heavyweight solution, as you have to work around IE<9's attachEvent
instead of addEventListener
, and perhaps provide something for older browsers that support neither.