29

Is inline event handlers considered a bad practice?

For example: <button onclick=someFunction()>Click me!</button>

If so, what are the disadvantages of using inline event handlers?

1

3 Answers 3

34

It's a bad idea because...

  1. Best practice suggests a clear split between content, style and script. Muddying your HTML with inline JavaScript (or CSS) is not consistent with this.

  2. You can bind only one event of each kind (per element) with on*-style events , so you can't have two onclick event handlers, for example.

  3. If an event is specified inline, the JS is specified as a string (attribute values are always strings) and evaluated when the event fires. Evaluation is evil.

  4. Functions denoted by inline event handlers must be global (or at least globally accessible), which is rarely the case these days; code is normally namespaced, or encapsulated in modules (thanks, @Sebastian Simon).

  5. Any content security policy (CSP) you're using would have to be (unwisely) expanded to allow evaluated inline JavaScript.

In short, handle events centrally via the dedicated addEventListener API, or via jQuery or something.

[2021 Edit]

These days, reactive frameworks have somewhat reversed this trend; events in reactive frameworks are normally specified as attributes e.g. in Vue:

<p @click='foo'>Hello</p>

...where foo is a method in the component scope.

HOWEVER, this is not true inline event handling; see @colin's comment under @adnanmuttaleb's answer.

Sign up to request clarification or add additional context in comments.

5 Comments

Here’s another good list why onclick and such should be avoided.
Also regarding point No.1 this can be solved, by using something like this onClick="handler1() || handler2()....|| handlern()" jsfiddle.net/ageck0bh.
v-on:click isn't really an attribute. It's a directive, and under the hood it will be using addEventListener vuejs.org/v2/guide/events.html#Listening-to-Events
Really old post, but I've done a lot of research myself on this question. With the last part about React or Angular, etc. it's important to note the distinction. These frameworks use templating engines and what seems like inline JS is not in-fact. They'll be passed through a compiler or templating engines that will output the code as proper event listeners on those elements. Raw HTML has no such benefit.
Regarding point 4: Current best practices include using ECMAScript modules. Modules have their own module scope, which isn’t global scope. Since on* attributes rely on global scope, you’d have to set the function as a global property, defeating part of the purpose of modules, specifically the benefit of encapsulation.
7

Aside from semantics and other opinions expressed in the accepted answer, all inline scripts are considered a vulnerability and high security risk. Any website expecting to run on modern browsers are expected to set the 'Content-Security-Policy' (CSP) property, either via meta attribute or headers.

Doing so is incompatible with all inline script and styles unless explicitly allowing these as an exclusion. While CSP goals are mainly about preventing persistent cross-site script (xss) threats, for which inline scripts and styles are a vector of xss, it is not default behaviour currently in browsers but may change in future.

4 Comments

I suppose you mean no javascript at all in the HTML. But since you use the term inline javascript, i'd note that according to the highest voted answer here stackoverflow.com/questions/19618571/what-is-inline-javascript inline javascript is only the between the script tags.. it's not what's in eg an onclick., that'd be an inline event handler.
at the risk of repeating myself, you're pointing out that an onclick is an inline event handler is semantics, or distinction without a difference. A "handler" is scripting, ergo inline script. The "highest voted" is only highest due to bias, SO has extreme bias to developers, not security professionals. Were there more like myself on SO there'd be a more even representation of security minded people voting. Having fewer votes does not make the answer wrong, and beside SO only allows 1 accepted/right answer but you'd be inexperienced to consider questions have 1 right answer in reality.
@barlop Inline event handlers are considered inline JS by a CSP: It will block them unless you specify 'unsafe-inline' or 'unsafe-hashes' in script-src.
the primary point is best described as, you want to let one molecule of water through the damn, but not the whole river... sure you can open the flood a little to get it through but you have no way to control that only that one thing is going to get through. Allowing inline scripts, even using a hash or nonce, without knowing what the code does, is just bad security. Do you know it won't pull an exploit and execute it in memory after the page loads? or something else just as bad? inline is inline, blind trust is just blindness and good feelings.
2

Building on @Mitya answer.

In most of the modern JS libraries React, Vue,..etc. inline event handlers are considered idiomatic, but most of the limitation mentioned by @Mitya are gone. As case study we will have look over Vuejs and compare it with point listed above:

  1. You can have more than one event-handler, look here
  2. Event values (handlers) such as onclick are not plain string but js expressions look here
  3. Global Scope problem simply does not exist (because your code will get translated minifed, repackaged by tools such as webpack or other).

In my own opinion, inline event handler enhance readability majorly, but opinions may vary.

3 Comments

React, Vue and Angular might look like they are using "inline event handlers" but they are not using an HTML attribute as described in the original question. They are using directives and under the hood they will be using addEventListener . Thus complying with best practise: developer.mozilla.org/en-US/docs/Learn/JavaScript/…
@Colin Can't tell you how many times I've had to explain that to those who want to put these directives up as examples of why it's actually ok to use HTML event attributes (which is is not)!
I am completely new to HTML. For me it looks like not using inline events is an advice which you give children. The author of this mozilla development page believes, that I am too stupid to work with inline events. Maybe I am. But that is my problem, not his. I normally don't create HTML pages by hand. I think, nobody does. Wether a HTML generation engine creates events in one place or all together in another place makes axactly no difference.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.