16

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?

Tibrogargan
  • 4,038
  • 3
  • 17
  • 37
haxxerz
  • 833
  • 6
  • 17
  • Does this answer your question? [Why is using onClick() in HTML a bad practice?](https://stackoverflow.com/questions/5871640/why-is-using-onclick-in-html-a-bad-practice) – Ivar Nov 18 '19 at 12:03

3 Answers3

23

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 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. You are faced with having to reference named functions. This is not always ideal (event handlers normally take anonymous functions) and has implications on the function needing to be globally accessible

  5. Your content security policy (CSP) will 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 v-on:click=foo>Hello</p>

...where foo is a method of the current component's data object.

Mitya
  • 32,084
  • 8
  • 49
  • 92
  • 3
    *"there would have been a time when the idea of storing data against elements inline in the actual source code, was unsemantic"*. I don't think that's true. The HTML source code is the natural place to store the data of the web-page. HTML defines the structure and hold the data. – Šime Vidas Jul 31 '12 at 14:49
  • 1
    Yes but data attributes store meta. I'm not against it, I'm just saying there was a time when this idea would have been questioned by many. Their usefulness, though, outweighs the concerns of semantics. – Mitya Jul 31 '12 at 14:50
  • But where else to store the meta data of an HTML element? What's the alternative? – Šime Vidas Jul 31 '12 at 14:52
  • OK, OK, edited it out. I do not dispute your point, I believe I had one, too, though, difficult to argue it though it is. – Mitya Jul 31 '12 at 14:54
  • Here’s [another good list](https://stackoverflow.com/a/43459991/4642212) why `onclick` and such should be avoided. – Sebastian Simon Apr 26 '18 at 19:02
  • But inline event handler are more easy to read and trace, at least for me. – adnanmuttaleb Jun 25 '20 at 06:36
  • Also regarding point No.1 this can be solved, by using something like this `onClick="handler1() || handler2()....|| handlern()"` https://jsfiddle.net/ageck0bh/. – adnanmuttaleb Jun 25 '20 at 06:53
  • `v-on:click` isn't really an attribute. It's a directive, and under the hood it will be using `addEventListener` https://vuejs.org/v2/guide/events.html#Listening-to-Events – Colin Oct 10 '21 at 15:49
  • It's literally an attribute :) I get what you're saying, but in terms of HTML semantics and its role in the markup, it's an attribute. – Mitya Oct 11 '21 at 13:12
5

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.

Stof
  • 414
  • 6
  • 14
  • 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 https://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. – barlop Jul 27 '19 at 00:11
  • 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. – Stof Jul 28 '19 at 02:35
3

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.

adnanmuttaleb
  • 3,070
  • 1
  • 27
  • 41
  • 1
    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: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#inline_event_handlers_%E2%80%94_dont_use_these – Colin Oct 11 '21 at 17:26