Welcome to another article on Building Better Web Pages. This article series comprehensively covers building an HTML document: easily learned, but rarely perfected.
Today’s article covers Unobtrusive JavaScript . While we await the day that content is properly separated from presentation and behavior, we will still no doubt come across many remnants of the old way of working with markup. One of these remnants is JavaScript events inline with HTML markup. This includes onsubmit, onclick, onmouseover, etc. The purpose of this article is to show you that, while technically allowed by the current HTML spec, inline JavaScript is a bad idea.
Solid Statement: Do not include JavaScript events inside your HTML tags. Put all scripting inside a separate file where it can easily be maintained or exchanged.
What is Unobtrusive JavaScript?
While not an official term, Unobtrusive JavaScript’s de facto principles are to separate your HTML from your JavaScript behavior and to provide users with progressive enhancement. The latter mean providing the basic form of a page (plain HTML) and then enhancing it via external files. Older methods relied on “graceful degradation” in case the user agent (browser) didn’t support all the script features. Progressive enhancement is better because it doesn’t attempt to use enhancements that would fail. Separating the content and behavior is the most important part of the concept. Now we’ll explain why.
Why is it Important?
The future of the web is modular. Proper web development will mean accessibility, ease of maintenance, and scalability. These practices are hindered by mixing different components together. This was not a problem in the old days, when a web page was shown on a computer monitor and nowhere else. Today, a website must accommodate hand-held devices like the iPad, all sorts of mobile phones/devices, and video game consoles. Every medium has its own requirements and capabilities. If you have JavaScript directly coded into some HTML markup, you have created a dependency between a certain JavaScript behavior and the content itself. If either the behavior or the content is changed (as much of the web does now, on a regular basis), you have a problem.
Modularity Problems
Consider the following simple example of an onclick event, improperly handled. After clicking the button, a JavaScript function from a separate file is called.
<input type="text" name="somename" onclick="dosomething();" /> |
Say I copy the HTML content from this page and want to display it elsewhere, such as a social network. You paste in your code and are all excited to have your visitors see it appear in a widget on your network. However, as soon as a visitor comes along and clicks that input, whatever was supposed to happen doesn’t, a JavaScript error occurs because dosomething()
is undefined, and JavaScript might no longer work at all on that page. The average user won’t even know what happened and they surely won’t be enjoying that content you were so excited about.
Maintenance Problems
Consider the previous code example. This time, however, we will be passing the input element in the form of some variable “x.”
<input type="text" name="somename" onclick="dosomething(x);" /> |
We like using our function, so it appears numerous times across numerous files. This presents a huge maintenance problem. One day we need to make some changes to the method and now require a different variable or use a new function name. The only way to handle the situation now is to search through all the files and make changes in every one.
Solution
The proper way to handle either problem above is to simply use JavaScript unobtrusively by ONLY including it in a separate file. Does this mean more work for you? Not particularly. In the above example, it would mean a lot less work. Additionally, with today’s available JavaScript frameworks, it is easy to set up these events. Not only that, but you can also organize all your events next to each other in the JS file instead of having them dispersed throughout the HTML.
Solid Reading
For building better web pages, any of the following books are a great! “Web Design For Dummies” introduces pretty much every aspect of design, including planning and research. If you are interested more in the concepts and ideas of proper markup, go with “HTML and CSS Web Standards Solutions”. Finally, for a more conversational tone, “Designing with Web Standards” is reading geared toward the practical application, rather than the concepts themselves.
Sorry, but I fail to see how you’ve made any relevant point here. Your assumption is that one wishes to do what you’re mentioning, which for most applications other than social media sharing.
This is the 6th result on google for ‘why is inline javascript bad’, and pretty much every result has not made a valid point yet.
No offense or anything, I just keep hearing that this is “bad”, but I don’t see any real reasons why so far other than these fringe cases.
cheers:)
No offense taken. I just reread this article and it still applies as much today as it did a year ago.
This comes up everywhere in my work, whether it’s commercial websites, freelance stuff, or enterprise web applications, so it matters all across the board. I made a whole lot of good points and don’t see how you wouldn’t find them relevant. Your sentence about social media has a typo so I don’t understand what you are trying to say.
I would ask you what your motivation is for looking this up? Is there some reason you wouldn’t want to do this? At the end of the day, it’s simply best practice. If you want to write bad code for whatever reason, that’s up to you.
Other people’s bad code just makes mine look better 🙂
bob does have a point. While I agree that it is better to move massive amounts of javascript code out of the HTML, I think it’s going too far to mandate moving all of it out. Consider this:
Blah
What does this do? Well you can see easily that, if Javascript is enabled, it will do some special thing, rather than go to page1. Now, I could see moving all of the behavioral aspects of the link out of the HTML, leaving you with something like this (if this were allowed):
Blah
Href has been removed here, since href is obviously behavioral and doesn’t really have anything to do with the markup. And then you would know to look elsewhere to figure out what that link does. The worst case is to have something like this:
Blah
And then in a separate file:
jQuery(“#my_awesome_link”).click(function() {
do_special_thing();
return false;
});
Because now you look at the HTML and see what looks like a link to page1, but you don’t really know what it will do unless you go searching through the project for some javascript hooking onto the thing and making it do something different. The problem is that the two parts that control the behavior of the link, the href and the onclick, are separated, making it difficult to determine the actual behavior.
I’m not sure what the best solution is, but obsessively moving all traces of Javascript out of the HTML is not it. I think some more work needs to be done to find the right balance.
Bryan, I think the comment system stripped out some code you had in there.
I can still see, though, that you are making the argument for readability. I contend that would be incredibly minor compared to the code modularity and maintenance ease provided by unobtrusive scripting, especially when today’s IDEs can easily take you to connecting code without knowing where it is. Also you were making some connection between navigation (href) and scripting (events), which are fundamentally and semantically different.
In an professional development environment involving things like a team of developers, version control, dev/qa/production servers, scheduled code deploys, and internationalization, unobtrusive JavaScript is invaluable. I have seen this bite people in the ass time and time again.