Post Archive
› November 10, 2005
Inline JavaScript: What's the Problem?
I have always been under the impression that inline JavaScript is a Bad Thing, presumably because it violates the whole separation-of-content-and-behavior idiom. I typically do what (I assume) most other people do in their scripts. That is, I bind an event to an element programmatically using some form of addEvent, usually after the page finishes loading.
But this approach has problems too, as I found out on a recent project. Specifically, for large pages or those visited by users with a slow connection, binding events onload can be inefficient and produce cross-browser difficulties.
So then, what is the problem with using inline JavaScript in moderation? After all, it is simply a name="value" attribute pair like all the others. Why is class="someclass" acceptable and onclick="dosomething(this)" is not? The fact that the browser passes the latter to the JavaScript engine instead of the rendering engine seems to be a minor distinction.
Then again, maybe this is all in my head, and that inline JavaScript is perfectly acceptable in the web developer community. I would like to hear from you. What other arguments for or against inline JavaScript can be proffered?
Comments
1. November 10, 2005 11:44 AM
2. November 10, 2005 11:44 AM
David Lindquist Posted…
Reading over my post again, I guess it all depends on the problem one is trying to solve. For simple binding of single event handlers to elements, I see no problem with doing it inline.
I understand that the addEvent method allows you to add multiple handlers to an element, but I only ever usually do this for adding onload handlers. And then, I really don't see why you couldn't just use window.onload = init; and have the init function call all the other functions you need. I can see the point of using addEvent for onload handlers when writing an API someone might include in their page which might already have handlers bound to the onload, but in that case, I would leave the onload integration up to the user of the API.
3. November 10, 2005 11:48 AM
Richard@Home Posted…
Also worth bearing in mind: If you use inline javascript and your client doesn't understand javascript, you've just sent a bunch of waste to them.
If you are worried about the page loading (and users clicking) before the javascript has run, try including the javascript on an earlier page. Hopefuly, it should have been cached meaning its there ready for the page that realy needs it.
4. November 10, 2005 11:50 AM
David Lindquist Posted…
Jeroen: how does class="something" give structure to the document? That still has to be interpreted by the browser somehow. I can make the point that the onclick attribute does not directly dictate the behaviour of the page; the function definition it calls does that. The onclick is simply another attribute in the document. How the browser interprets that is inconsequential.
5. November 10, 2005 11:52 AM
6. November 10, 2005 12:05 PM
David Lindquist Posted…
Also, I should clarify that I do not mean to say that any and every bit of JavaScript is suitable for being used inline, only simple function names that call methods defined externally in some linked .js file.
7. November 10, 2005 12:26 PM
liorean Posted…
Well, off the top of my head:
The escaping and parsing systems of HTML/XML and JavaScript are different, and can introduce problems with things like nested quotes or JavaScript operators such as
&&. This of course goes both ways, for writing HTML in JavaScript strings you have the opposite considerations. And worst of all is when you have them nested more than once...The text in the event handler is made into JavaScript. But some of the specifics of this are badly documented (as evidenced by the fact that iew has entirely different event handling than nn had while doing it's best to emulate the exact behavior of nn, but similar enough to behave roughtly the same in the then-being use cases) and not obvious. This makes both debugging and learning to use them harder than it should be. Also with the introduction of DOM there are plenty of opportunities for confusion about what is HTML and what is JavaScript, and what kind of parsing happens when.
Inline JavaScript means decentralised script storage, which is bad for a number of reasons:
The event handlers are inline in the HTML, but the code they call on may be inline, embedded or external. This means you can have an event trigger at a time when the code in the handler calls on non-existant functions or objects.
If you have the same script on many pages, the same principle problem as with inline CSS occurs: if you have to change something, you need to change in many places. If you have a dynamically generated document this can be solved by moving event handlers out to templates, similar with cashed dynamically generated pages (precompiled), but the essence of the problem is still there, just delegated to another instance that may introduce it's own problems. Finding all places you need to change can be a problem. If you move the event handler into the JavaScript, you only need to look at one place, at least. If you have all JavaScript in one file, you can change once for many documents.
Debugging gets complicated when errors may be outside of the realm of JavaScript. Such as the event triggering before the external JavaScript it depends on has been loaded.
Development sicknesses that can not be seen when the document is local. For example, when documents are local, script access will be much faster and thus you never see the types of errors that can happen when, for instance: a server serves the script with the wrong content type; or the request times out.
8. November 10, 2005 12:31 PM
Joe Tan Posted…
What I've done for some projects at work is instead of binding functions to window.onload, which as you mentioned fires only when all images are loaded, I added a script tag to the end of the html which fires off the functions. This allows the functions to fire a little bit earlier, when all the html is loaded. And if we're just manipulating the DOM in some way (like adding event handlers and whatnot), then all you really need is just the html to be there.
I think in IE (or maybe Firefox, can't remember which), there is actually an javascript event for this. however, I dont think it's widely supported.
9. November 10, 2005 01:01 PM
Roy Posted…
On top of what everybody is saying, if you have inline JS, like onclick="foobar()", and you accidentally rename foobar() to fooBar(), the browser returns a nasty error message. In the case that you rename a CSS class, the error is a lot more graceful (just doesn't display properly).
10. November 10, 2005 01:07 PM
David Lindquist Posted…
Thanks for the info, liorean. Very informative, as always. But I have to say: in all my years of web development, I don't think I ever experienced any of the problems that you cite. Certainly those have got to be rare "corner cases" or theoretical problems? Would not there be just as many problems with the new-fangled event binding?
11. November 10, 2005 01:38 PM
liorean Posted…
I really doubt you haven't encountered the problems. You're just so used to them by now, you don't notice them any longer. Also I bet you both understand what you're coding and the way the technologies work together more than the myriads of people having trouble with this posting on for example CodingForums. But of course, the DOM isn't any easier to grasp and learn. It's benefits are not directly evident either. You need to go into the domain of ideology to really argument for one side or the other. There is no generic "this is the right thing to do" answer, because things may have entirely different priorities for different cases. For example, a site with hundreds of thousands of pages which all are precompiled from templates will not have many problems with modifying the code in more than one place, while a hand coded site with maybe fifty pages may easily miss correcting the code here or there. A site that uses JavaScript and events for everything is more likely to encounter these problems than a site using slim scripts for enhancing some features of the site.
12. November 10, 2005 03:08 PM
Jonathan Snook Posted…
I think the key point of the post was code execution timing -- especially for larger pages where the window.onload event will take some time to fire. A person could be halfway through a form before any of the behavioural level got applied. Look at it this way: imagine how popular CSS would be if it never got applied until all the HTML and images were downloaded (I'd guess, not very). Mozilla, Opera and Safari need to follow IE's lead with additional event handling (readyState). Even better would be the ability to attach an event to an object id that would be attached at the moment the object was instantiated. Like, attachAtInstantiate('objid', onclick, functionname);
13. November 10, 2005 06:29 PM
liorean Posted…
Well, for that problem, see dean.edwards.name/weblog : The window.onload Problem - Solved! for a nice blog entry. If the DOMContentLoaded event could be made standard I'd rejoice.
14. November 11, 2005 09:13 AM
Jeroen Mulder Posted…
David, onclick, as the name suggests, defines a value for a certain type of behaviour. That point isn't as much an argument against inline Javascript, but more against the use of the onclick attribute, as it implies behaviour (you're right saying the value defines it).
15. November 12, 2005 12:27 AM
sosa Posted…
Just wna to point, that inline javascript isn't analogous to name="value" but to style="font-family:serif;color:#f00;" and that isn't very different from using an old plain tag
16. November 13, 2005 09:38 AM
Douglas Clifton Posted…
I don't have any problem firing events using "inline" Javascript such as onclick="function()." What bothers me, and I still see this all the time, are pages that are interspersed (often with no rhyme or reason) with Javascript code.
What bothers me even more is that this practice is considered acceptable, and even encouraged, by sites that offer "features" to the site owner. Technorati, Google, the list goes on and on..."fill out this form, then cut-and-paste resulting code into your site's HTML..."
Granted, one of the reasons the Web has had such explosive growth is because it is approachable by the average user -- we all don't have to be professional developers to have a personal site or a blog. But by encouraging poor practices, you end up with millions of pages that are invalid, sloppy and browsers that end up bloated with code designed to deal with sloppy, invalid markup.
17. November 13, 2005 09:00 PM
andr3 Posted…
From my personal experience, i'd say it's not always bad, but should be avoidable. I've worked on a fairly-sized CMS and during the process i debated the issue of inline Javascript with myself. I ended up attaching *some* events in the markup, and now, as i prepare to restructure my markup, i'm facing problems due to static javascript function calls that i don't want to keep the same.
Maintainability is a big issue that shouldn't be ignored.
The only situation in which i don't see this as a huge mistake is in form verification, specially if the markup is being generated on the server side. That's probably just me, but i don't like to see the world only in black or white. ;)
18. November 14, 2005 05:33 PM
Dustin Diaz Posted…
I mentioned this over of Jeremy's blog, but I'll say it again here:
I think the biggest argument inliners have is how to tie in JavaScript built in with a much larger architecture. I too (agreeing with Jeremy) believe that there is always another workaround that one has yet to think of.
It should always be as easy as passing in a className of a sort and use that as a hook to add behavior. on[event] is a mirrored effect of the style attribute, but for JavaScript.
In the grand scheme of things, usage for onclick seems well suited for modules where its sole purpose is a behavior... meaning, there is no "degradation for non-js-enabled browsers"...on the contrary, that's a case for bad development to begin with. Unobtrusive JavaScript just makes sense.
19. November 15, 2005 11:19 AM
me Posted…
As a lazy person, I feel the amount of code needed to accomplish things in the 'better' or 'more advanced' was is just too much.
for example
var item=document.getElementById('item');
addEvent(item, 'click', popfunction(e) { return MyFunc(); } } function MyFunc(e) { if(e.preventDefault) e.preventDefault(); return false; }
This is just to achieve the same result as
a onclick="popfunction(this); return false;"
Jeroen Mulder Posted…
Exactly the same as why you don't use inline CSS.
Inline Javascript directly dictates behaviour in a markup language that should be used to give structure to a document only. Using classes and IDs you classify and identify (wow, I am such a Sherlock) parts of your markup that contain a particular type of information. Then you can apply behaviour on top of this type of information, resulting in a nice seperation of behaviour and structure. As you've most likely seen with CSS, this seperation has many advantages relates to purity and maintenance.
Furthermore, unobtrusive Javascript tends to focus more on enhancing an existing interface, instead of building one. This subtle difference is important when you're talking about graceful degradation.
Some people might accept inline Javascript, but, while unobtrusive Javascript might be more work and proposes more challenges, I feel it's worth the extra effort.