Six JavaScript features we do not need any longer
Notice: The following is a “best practice document”. You can follow its advice and live happily ever after, but there might be situations where you cannot apply the ideas mentioned within. This is especially the case when you have to maintain an old product or complex web application. You cannot replace everything in those in one go – as you are very lucky indeed if you get the time and budget – but you can tackle those step by step.
According to many web designers at @media2005, JavaScript is sexy again, and in demand. Ajax is the new CSS was a quote in one of the presentations, that – taken out of context – makes my stomach go wonky.
Working largely with b2b sites and restricted environments, I never knew it was out of fashion.
It is a tool, much like a shovel, a screwdriver or a towel. While a towel is handy in every situation, as every HHGTTG reader knows, JavaScript has its place and its merits, but also its limitations and places it shouldn’t be applied to.
You can use a screwdriver to screw in screws or to clean your ears, however, the latter needs real skill, determination and a lack of fear of injuring yourself. It is much the same with JavaScript, you can use it for great things, but you can also use it to make a product inaccessible, confusing and not usable.
Here are some danger signs you encounter in many a bad script example and tutorials written in the spur of the moment rather than following proper research.
Things that should make you go <vader>Noooooooooooooooooo!</vader>
document.writeWhat this does is write out content to the HTML document, inside the body of the document and merrily mixed with the markup. Bad web developer, bad! Go to your corner! A better solution: reach the element you want viagetElementByIdorgetElementsByTagNameand then insert your newly created content (viacreateElementandcreateTextNode) there.<noscript></noscript>This you encounter a lot in “Accessibility Tutorials” and it should “make sure that every user can use your site”. Actually, it is a sign that the script you use (or did) is bad and should have never been used in the first place. It is like using white-out on the wallpaper after you used your crayons there. Comment: I was asked to clarify this, as web application developers who have to rely on JavaScipt (which is a flaw in the application design IMHO) use noscript to tell the users they need JavaScript enabled. Normally this is added as a warning message at the start of the non-working page. The more logical option in this case would be to have the "no JavaScript" message in the document and replace it with a link to the application when Javascript is available. Check this example page on how to avoid noscript. Turn JavaScript on and off to see the difference.href="javascript:", onclick="javascript:"There is no such thing as a JavaScript protocol on the web. Links use protocols to connect documents. Create real links or don’t use any link at all – do or do not, there is no try!onclick="void(0)"Why would one put effort into creating something that by definition is not doing anything? Glossing over bugs and bad scripting, that’s why. A link that only points to a JavaScript function should be added via JavaScript.document.all , document.layers, navigator.userAgentUnless your defined project environment is MSIE 5.x and Netscape Communicator 4.x (my condolences if it is), there is no need for that any longer. Object detection is so much better than trying to guess what the browser in use is, and the W3C DOM is also more likely to be used in future UAs than the bespoke Netscape or Microsoft ones. (If you say “huh, what?” now, just trust me that everything withdocument.getElementByIdis much more stable than the other two mentioned earlier)onmouseover="myCall('I','pity','the','foo',1233,'I aint going on no plane')"Anything crucial to the user experience that you generate via JavaScript needs to be in the document anyways – for users without JavaScript. Reusing this markup is a lot easier, cleaner and more maintainable than sending a lot of parameters. If there is any reason to send parameters, a simple ‘this‘ does the trick in most of the cases, as you can navigate through the DOM from there.
On request
And what about innerHTML?
As some pointed out in the comments, innerHTML is another way to create content on web sites. In some cases, it is even the fastest method, as Peter-Paul Koch found out when comparing methods to generate content. However innerHTML is neither standard, nor applicable to any DOM scripting outside the browser environment. There is an excellent discussion about innerHTML on developer-x. My personal view? innerHTML makes it a lot easier, but advertises HTML documents as strings rather than node trees, and that makes it hard for junior developers to go further in their scripting ventures.
Partly inspired by Robert Nyman’s recent post about JavaScript


June 21st, 2005 at 10:51 pm
June 23rd, 2005 at 9:22 am
June 24th, 2005 at 3:39 am
June 30th, 2005 at 7:55 pm
June 21st, 2005 at 8:26 pm
Chris,
Good write-up!
I’m happy to have partly inspired you and that you help spreading JavaScript awareness. :-)
June 21st, 2005 at 8:59 pm
In response to #1 and #2.
I wouldn’t say they were completely redundant, PPK is a javascript genious, but I do believe they have their place.
June 21st, 2005 at 10:24 pm
As I’m poorly-versed in designing with JavaScript, I imagine I’m your target audience for an article such as this. I would be interested in more detail as to why
<noscript />is never acceptable: an amusing analogy and simple declaration that it’s “bad” is neither convincing nor informative.Edit I thought it was pretty obvious: noscript is to be used when you want to offer a fallback for functionality that is only available with JavaScript. Unobtrusive JavaScript, however, is per definition never needed, but only enhances functionality that is given by normal HTML and the backend. Therefore noscript is not needed any longer.
June 21st, 2005 at 10:32 pm
Bravo, a definite goal to work towards. My least-favorite is using a document.write to write out a script element that calls a remote javascript that uses document.write to put content on the page. I recently had a client with that setup who then asked if the resulting document.write could write another script element to call another remote script which would then perform some action. Aaarg!
June 21st, 2005 at 11:05 pm
Nicely written javascrip NOT to-do. You could, however, fix the links. All of them are borked in one way or another.
Edit Ah, the wonders of encoded quotation marks. Cheers. Fixed now.
June 21st, 2005 at 11:12 pm
Great write-up. No I just have to convince my co-workers not to use inline javascript calls! :-/
However, I discovered a little flaw in your last example; ‘I ain’t going on no plane’ will most definitly not act the way you want it :-).
Edit Now it does. I love it when a plan comes together.
June 22nd, 2005 at 12:19 am
About getting rid of old practice JavaScript and converting to more modern methods.
June 22nd, 2005 at 12:30 am
Someone’s been watching Star Wars! Also, innerHTML is good for inserting content as well (and faster) as the methods you mentioned.
Edit Could be, however, innerHTML is neither standard, nor applicable to any DOM scripting outside the browser environment. There is an excellent discussion about innerHTML on developer-x. My personal view? innerHTML makes it a lot easier, but advertised HTML documents as strings rather than node trees, and that makes it hard for junior developers to go further in their scripting ventures.
June 22nd, 2005 at 1:10 am
Nice write up, though I disagree with some of your assertions. In case you weren’t aware, Mozilla doesn’t allow the use of
document.write()when documents are served asapplication/xhtml+xml(details), so that helps your cause right off the bat.Your point about
<noscript>is well taken, though it still has some important uses. Many Web applications require JavaScript support, and without this, there would be no way to display an appropriate message to the user if JavaScript is disabled.Edit Via a bridge page for example? For Flash, Designers learnt that “if you can see this button continue” is a lot better than guessing the Flash Version. For JavaScript we can do the same. The message that JavaScript is necessary can be replaced by a link when JavaScript is available.
Also,
navigator.userAgentis still used a lot for tracking purposes. While object detection is good in many cases, sometimes nothing beats a good old fashioned user-agent string sniffer for incorrect implementations or special features (i.e., how else would you know someone was using Windows XP SP 2 without searching for “SV1″ in the user-agent string?).Edit Why would you for a web site? A tracking script/web application is a totally different animal.
June 22nd, 2005 at 2:34 am
Great pioints.
I have one dumb question though, if you need an <a> tag, but don’t want it to link anywhere, what do you put for the href attribute?
Edit Why do you need a link that goes nowhere? If the link only fires a JavaScript event, then create it via JavaScript. See the datepicker example in the unobtrusive JavaScript course for a solution.
June 22nd, 2005 at 4:51 am
I’d still make the case for allowing javascript: links, if only to have the following: href=”javascript:;”
This is very useful in situations where you are adding a link to the document through the DOM. Of course, you could do href=”#” and make sure to kill the default action onclick, but it is much nicer to just be able to do href=”javascript:;” when dynamically generating “JS links”.
Edit I disagree, without JavaScript, you have a dead link. If the link only works when DOM is there and points to a function, then use the DOM to generate it.
June 22nd, 2005 at 5:22 am
For all it’s worth, you can just about add “.innerHTML” to the list as well. You really should use the DOM for stuff like that, even thouh it’s an order of magnitude slower.
Edit See my comment to Dante’s comment.
June 22nd, 2005 at 7:05 am
without document.write, including third party scripts such as google ads becomes more difficult.
as for “javascript:” , i understand the reasons for not using it, but in an application built in javascript (eg gmail), why not use “javascript:” links? otherwise you are generating a non-anchor element such as a span, setting up onclick handlers, and for ie :hover compatibility on non-anchor elements, setting up onmouseover and onmouseout handlers instead of being able to use the built in css rules… more work for no good reason. another small point is that the “javascript:” links show up in the status bar, which is nice for debugging and hacking on web apps. so, for most web pages, yes, we don’t need “javascript:”, but i do see benefits in using it in web apps.
Edit YMMV, but again why not generate the link via the DOM then? You can create a link as easily as creating a span…
June 22nd, 2005 at 9:19 am
In this article, you are advised to avoid 6 Javascript features from now on. The good thing is that having read the article does not automatically make you a supporter of its content.
…
June 22nd, 2005 at 10:36 am
Nice article..
I’ve just knocked together an on-line parser that should ease the pain of migrating innerHTML to DOM equivalents.
It’s very beta so some manual intervention will be required for very complex innerHTML strings.
Demo: http://www.frequency-decoder.com/demo/begone-innerHTML/
June 22nd, 2005 at 10:50 am
very useful info for a lot of people. Good work
June 22nd, 2005 at 12:00 pm
All in all, this is a good starting point, and I hope that in five years people will refer to this and say, "he said it first."
However, today’s Real World makes mincemeat of most of these ideas.
document.write(),document.layers,document.all, and the use of null event handlers are a legacy of the limitations of 4.x and earlier browsers. Little more needs to be said about them.On review, I figure that
noscriptis also redundant.The fundamental idea behind these items is that a client will always bow to the needs of accessibility and agree that the app they’ve commissioned ought to be available in a non-JavaScript version. However, when faced with the cost, hassles, and product of that specification, they usually quail and say “no, thanks” – figuring that in the event they’ve made the wrong decision, they can commission the additional work.
Nor is that a poor strategy, in the hands of a good team.
Meanwhile…
javascript:URI’s:I agree with the assertion that under no circumstances should a
javascript:URI be written directly into markup. However, using them consequent to changing thehrefof a given link. While it’s true that afterwards I can fire an event onclick that executes the script I need, and returns false on the activity of the link itself, that seems awfully hackish when you want a script to be invoked when the link is followed anyway. In other words, it’s there – might as well use it when appropriate.Useragent string based detection
I’d looove to let this one go; it’s dangerous. But I can’t – not as far as I know. If one needs at runtime to distinguish Opera and AOL from MSIE, and Safari from Gecko, the most reliable way to do that remains the user agent string. If you can point me to a reference that proves me wrong, I’ll be grateful as all get out. (I’ve tried poking at clientInformation and document.body, for telling the difference between MSIE and Opera, but even these approaches are qualified, and I’ve never been clearly successful with them.)
Using the event handler to pass arguments to its associated function
Technically, you’re right. Hell – technically, the event handlers don’t even need to be present in the markup. However, removing those arguments from the event handler and then checking for state in the function itself is often (usually?) quite a bit more verbose (and harder to master). Also, event bubbling can in some cases create issues that require a handling script to be still more verbose.
June 22nd, 2005 at 12:24 pm
That is why I added the Notice at the beginning. However, the cost and hassles are defined by you as the developing company, if you offer the JavaScript dependent version as a cheap version and sell an accessible one as the more expensive then it is no wonder no client and no out-of-the-box vendor cares about standards. IMHO a lot of times our big mistakes is plunging into development far too early rather than properly designing the applications and test it on the future users via wireframes.
If the link only makes sense when JavaScript is there, create it via JavaScript, as easy as that.
The question is why do we need to know the user agent? The only real use I can think of is site metrics and statistics. If we design our web applications with user goals in mind rather than “has to work in browser xyz and abc and cde with that and that setting” we wouldn’t have to care about browsers at all. How many internal applications like timesheet systems have we encountered so far that were bloated and useless, mainly because they were designed with technical specs in mind rather than caring what the user needs to do with them.
Better to have a verbose function than a verbose tagsoup, I say. Maintenance is a nightmare when you mix scripting and markup, and you need a developer who knows both to change and fix things. And those are not growing on trees. There are a lot of scripters not knowing anything beyond HTML 3.2 or MSHTML and a lot of web designers who only know JavaScript as an include in Dreamweaver. Separating your functionality out to the JS means you can fix without making things worse. Mixing them will always lead to yet another hotfix.
June 22nd, 2005 at 3:03 pm
De plus en plus, Javascript regagne du terrain sur le web, et c’est tant mieux. Mais ça n’est pas une raison pour coder comme un gorret. Cet article présente quelques trucs à éviter, ainsi que les moyens de les remplacer.
…
June 22nd, 2005 at 4:39 pm
If you’re saying that the page should be functionally equivalent with JavaScript turned off, why bother using JavaScript at all?
Edit To make it easier for users with JavaScript enabled? An example is a form that does not reload the page when you forget to enter a field but tells you immediately about it or a gallery that loads the images without reloading the page.
June 22nd, 2005 at 6:27 pm
Fairly useless info, thanks for nothing. With the exception of #5, all of your claims are debatable at best, and shortsighted or downright wrong at worst.
Edit Hello Marty, feel free to back up these accusations with examples and explanations any time.
June 22nd, 2005 at 11:28 pm
As for the javascript: pseudo-protocol, my opinion is: if you’re not providing a means of navigation, don’t use an anchor. Mousecursor and hover-effects can be achieved using CSS and/or javascript on any element.
June 22nd, 2005 at 11:51 pm
What if you have a drop-down with something like onchange=”this.location.href=selectedIndex.something”
and no button that says “Go”, wouldn’t it be ok to use a
Edit In that case you could also use the DOM to get rid of the “go” button instead. However, onchange is not easy to use with a keyboard and might be impossible with voice recognition or screen readers. I discussed that problem in the first chapter of the Unobtrusive JavaScript course
June 23rd, 2005 at 2:44 am
I use
June 23rd, 2005 at 3:00 am
actually i do. i think i just like seeing stuff like javascript:sort(‘by_frequency’) in the status bar, something onclick handlers don’t do automatically. of course, this is for something that requires javascript — usually i will do the “correct” thing and just enhance the page with onclick handlers.
another uncommon reason is when you need to provide browser specific instructions to the user (eg how to install a bookmarklet in the user’s browser).
June 23rd, 2005 at 10:23 am
I entirely agree with all 6 points.
Regarding point 5, you say
“Unless your defined project environment is MSIE 5.x (…)”
but even MSIE 5.x support document.getElementById().
One point which IMO should be entirely removed ASAP from browser support is “javascript:” pseudo-protocol in links. You all should request this for MSIE 7 at MSIE 7 standards support blog (read by MSIE 7 dev. team):
MSIE 7 Web Standards support and requests
June 24th, 2005 at 1:26 am
Great article. Since my javascript knowledge is very limited, I must say that I learned a bunch and was equally humbled by the rest. I have a question/request. How can I get rid of the javascript calls in this html and call them with a class instead:
E.g. i currently I am calling ypslideoutmenu.js with….
<li class="projects"><a href="/projects/" title="my projects" class="'menu4" accesskey="7" onmouseover="ypSlideOutMenu.showMenu('menu4');" onmouseout="ypSlideOutMenu.hideMenu('menu4')" >PROJECTS</a></li>and I’d rather have it look like…
<li class="projects"><a class="'menu4" href="/projects/" title="my projects" accesskey="7">PROJECTS</a></li>Edit Terry, have a look at the CSS and JavaScript Separation chapter of the course :-)
June 24th, 2005 at 9:27 am
An interesting article. Some very good points made. Having just converted a web application that used (religiously) all 6 points you argue against, I whole heartedly agree with most of your points. The only two points I would disagree on are:
While holistically I agree that object detection is the way to go, and not browser detection, there are times when it’s needed.
One example of this is rendering issues with different browsers or operating systems. eg, winIE and drop down boxes. Also scrollbars on FireFox for the Mac. Both are drawn last by the rendering engine, on top of all other content. To work around these issues, browser/os detection is needed.
Another example is that sometimes object detection fails. There are a couple of objects that will return true in winIE, and yet are not implemented (took me a couple of hours of headscratching to work this out).
If I may also weigh into the issue of making non-javascript friendly pages… :) Often projects are very constrained in budget and time. When these get too tight, the only options are to reduce functionality, quality of the application, or to remove features. From a business viewpoint, removing the non-javascript friendly feature is a no-brainer. For corporate environments, and for most users, requiring javascript is not a problem. Sure, this might make your application unusable for some users, but that’s a business decision based on cost/benefit. If very few users do not have javascript, then the cost of not supporting them might be far less than if you did support them.
June 24th, 2005 at 5:21 pm
document.write = easy
document.getElementById(createElement) = difficult
Unfortunately, the righteous developer will always choose difficult. Of course, he’ll go 100% over budget and miss all his deadlines.
June 24th, 2005 at 6:22 pm
re: #32, let’s not forget:
document.write = leaks memory, limited to documents
element.innerHTML = pretty good compromise
June 24th, 2005 at 9:43 pm
What Mr. LePera said.
…Wanted to give some meat to a couple of my earlier points.
WRT user agent detection, yes, in that perfect world where browsers behave exactly as documented (and are standards compliant within the domains of entire featuresets to boot) and all developers have account reps to hide behind, we would know which objects to test for. But thanks to stakeholders who STILL don’t get (and never will get) the fact that THE WEB IS NOT PRINT AND NEVER WILL BE, we need to keep .userAgent around. Same principle as stylesheet hacks.
Reason #2 to rewrite links to javascript: URLs instead of using the onclick handler:
What if the user isn’t using their mouse? (How many events do you want to handle? And how do you want to deal with the differences in key binding across browsers?)
Assuming progressive enhancement, if the whole point of the link is to invoke a script in scripting-capable environments, then put the damn function behind the href instead of an event handler.
Just so we’re clear, a lot of my talkback is founded on foul experience of dealing with the other 80%… the clients who never refer, who want everything just like THAT down to the last pixel, and who effectively force us set our hourly rate 11.1…% more than we’re actually aiming for, so that we can bludgeon them with a discount to encourage timely payment.
Edit Tabbing and hitting enter actually does fire off the onclick event in browsers, therefore onkeypress and onclick together is more harmful than helping. Assistive technology also allows keyboard users to define a key to fire off onclick events, like voice recognition software executing click(). More under what about onkeypress.
June 24th, 2005 at 10:07 pm
Re: Edit on my earlier comment 13.
I was arguing for the case when the DOM is used to generate the link. I think the case for that is very legitimate, especially if you could have an assortment of possible event handlers, saving you from having each possible one try and cancel the event.
June 25th, 2005 at 1:15 pm
I think people saying that javascript: URIs are okay when you are creating them with Javascript are missing something.
The fact that they break when non-Javascript users encounter them is merely a symptom of a larger problem – that they are links that aren’t links.
This larger problem has other symptoms. It particularly bugs me when (with Javascript enabled) I click on a link ***to open in a new tab***, only to find that it’s some Javascript noob that hasn’t made a proper link.
If it’s a link, then make a proper link. If you want stuff to happen when that link is activated, use an event handler instead of that brain-dead javascript: nonsense. If it’s not a link, then don’t create a link in Javascript, create some other element with an onclick handler.
June 27th, 2005 at 3:40 am
Love your example page to avoid noscript!
June 27th, 2005 at 5:36 pm
Read the article Six JavaScript features we do not need any longer now. It’s a good roundup on common JavaScript techniques which are totally absolete these days. Even if you don’t sign it, it’s definitely something to think about.
…
June 29th, 2005 at 7:15 pm
I would tend to agree with every one of the six points you’ve mentioned, but after spending quite some time on designing the template for my blog, I must agree with Tim about the javascript: behind the href. IE with its lack of full CSS support, means that you can design a website that uses elegant code, but does not work to its fullest capability for 80% (appx) of internet users.
Scenario: Need to change the style of an element or pseudo-elements, for the purpose of creating hierarchical menus.
The right way: Put the menus and sub-menus in nested
ultags, and use the :hover pseuodo-class to display/hide the menus.Pros: No javascript. Extremely simple to code. Compliant with standards.
Con: Won’t work on IE.
The almost right way (imho): Use CSS, but put an anchor tag on the pieces of text for which you need hover functionality to work, and use href=”javascript:;” as someone mentioned above.
Pros: No unnecessary Javascript (other than the bit in the anchor tags you added). Simple.
Con: I don’t know what happens when you click on the ‘non-link anchors’ when Javascript is turned off. Could do bad stuff.
The almost right way (according to what this article prescribes): Use CSS, and add “javascript:” using DOM.
Pro: Ideal way of adding “javascript:”
Cons: Not simple. Verbose Javascript used where none was really required, just to get around IE’s lack of CSS support. It might have been simpler just to use Javascript to create the menus in the first place. When you mouseover on the links which should bring up menus, if Javascript is turned off on IE, you won’t see the menus. Result? A semi-functional website. Unless of course, you add some more code to ensure that your site has the data in the sub-menus displayed automatically if JavaScript is disabled. Which means, more complexity.
On my blog I preferred not to provide functionality that required breaking these rules, but that is a choice that someone who’s getting paid to do his job, doesn’t normally have.
Of course, this is a layman speaking. I reserve the right to stand corrected.
Good article otherwise :)
July 3rd, 2005 at 1:17 pm
Chris nennt 6 JavaScript-Befehle, die seiner Meinung nach obsolet geworden sind und zeigt, wie es anders besser geht. Für Webseitenoptimierer.
…
July 3rd, 2005 at 10:40 pm
While coding the layout for my (soon to be launch) company website, I had this sudden itch for making the interface a bit more unique. I wanted the entire sidebar (menu, news, updates,… etc) to be static while the rest…
July 4th, 2005 at 8:24 pm
You’re all missing the point about javascript: or void() HREFs in links – the real point is that a link with no HREF is not accessible to the keyboard – so you have to put something, even if you have a separate onclick handler.
So what do you put? You can use a javascript:functionCall() but then you have to have a function in the global scope; if the link is created within an OO function, then you can keep it OO by adding an onclick handler there … but … you still have to put something in the HREF, otherwise it’s not keyboard accessible.
So what do you put? Well we’re in a circle here, and there’s no good answer afaik. What I usually do is put “javascript:void(null)” because it doesn’t do anything else, but I’m still not happy with it – semantically it’s as dubious as “#”, if less hassle to use, and it doesn’t display helpful information in the status bar.
Maybe the real problem here is the necessity – but can that be helped? Should browsers allow keyboard access to links with no HREF, when by doing so they might make keyboard users have to tab through endless anchor targets, which don’t in fact do anything at all.
Edit
Welcome Brothercake, btw, cool to have you around. You are right it is a dilemma, however, what we can do is generate a link to an anchor and create an anchor in the element we want to show and hide. This also saves us the trouble of moving the focus to the “shown” element.
July 5th, 2005 at 8:11 am
Good One … keep it up :)
July 7th, 2005 at 7:19 pm
That would be feasible if it’s appropriate, but it won’t always be – following a target implies moving to a location, so either the page jumps (which clients would complain about) or you’d have to contrive that not to happen (by creating an element specially, and positioning it in the right place, but then isn’t that more of a hack than what it’s trying to avoid?)
My core point is that it’s over-simplistic to say you shouldn’t use “dummy” HREF values in links, because there are situations where that’s the only choice. But I will agree you shouldn’t use them in static HTML - only in HTML that’s generated through scripting.
July 19th, 2005 at 1:28 pm
Nice Article. It’s good to see a lot of discussion, but I am a little confused – the title indicates that these features should not be used at all, whereas between us we seem to have come up with at least one valid reason to use each feature, in certain exceptional cases.
Do you still think that these are all “must avoid’s” or just “should avoid’s” ?
Edit Read the title :-) “We don’t need any longer”
July 24th, 2005 at 5:56 pm
1.
<span onXXXX="vbscript:dosomething" >aaaaaaa</span><span onXXXX="perlscript:dosomething" >if browser can use perl</span>2. different scope chains between <A href=”dosomething”>aaaa>/A> and <A onclick=”dosomething”>aaaaa>/A> .
3. using
Edit
Making non-clickable elements clickable is not really advisable from an Accessibility point of view. And why should I add extra HTML to make things work?
July 24th, 2005 at 8:56 pm
I’m just assuming here, but can’t you just leave the href attribute out of the anchor tag, but still allow keyboard access by use of tabindex or accesskey?
July 25th, 2005 at 10:12 am
every single one of these points was moronic. you basically do not understand that there is no such thing as ‘do not use’ — only use with wisdom. every ability has its time and place and with hack-fu can be harnessed for great gain.
Edit You did see:
August 1st, 2005 at 8:50 pm
What a bunch of trivial crap! Sounds like a bunch of junior programmers having an ignorance fest…
Edit Enlighten us, oh wise one…
August 1st, 2005 at 10:57 pm
For the most part, I agree with you. However, innerHTML is indispensible in some of my web apps- the server passes HTML back to the page inside an XML document via XMLHTTP, and actually parsing it into an XML document then integrating it into the DOM would add a completely unnecessary level of complication. I understand your point about it not being standard, but since at least IE, Firefox and Opera support it, it is basically an ad hoc standard, and should be adopted as an official one.
August 2nd, 2005 at 7:46 am
DOM yet not a perfect.
I just have found that you need to specify default value of checkbox differently:
in2 = document.createElement(“input”);
in2.type=”checkbox”;
//for IE
in2.setAttribute(“defaultChecked”,”true”);
//for Firefox
in2.setAttribute(“checked”,”true”);
This world will never be perfect…
August 3rd, 2005 at 4:20 am
I have spent some time playing around and found that IE is not
a good brower to demonstrate DOM.
Here is a second issue which doesn’t work in IE6,
but works under firefox and konqueror.
IE6 doesn’t understand names of forms/input files:
var mybody=document.getElementsByTagName(“BODY”).item(0);
var f = document.createElement(“FORM”);
in1 = document.createElement(“input”);
in1.type=”text”;
f.appendChild(in1);
mybody.appendChild(f);
in1.setAttribute(“name”,”myinput”);
in1.setAttribute(“value”,”myinputvalue”);
f.setAttribute(“name”,”myform”);
//returns “myform” value in IE/Fireforx
alert(document.forms0.name);
//works in Firefox/Konqueror only
alert(document.myform);
alert(document.myform.myinput.value);
August 16th, 2005 at 3:27 am
This are good ideas, but they are personal preferences, maybe guides, but fall short of “best practices.”
1. Sure document.write is on the way out in a few years, but it does offer a way in include a link to browser specific CSS–in the head section–that is only needed to correct browser bugs. Yes, there are hacks, but these are hacks and, IMHO, not acceptable.
2.
<noscript></noscript>, which in practice I usually neglect except for client requirements, is a best practice. Just like an if or case statement should test for the most likely first, in many ways your page should handle the most like Javascript enabled first and then noscript. Not the other way around. For example, in a situation I used a dynamic menu displayed when needed, but witha static menu is use. The page adapts to the client.3. I agree the href should be a link. One to use when JavaScript in not enabled. But, there is no reason not to use an href="javascript:fx();" when that is the known requirement. Hiding it through dynamic assignment is just a game. If that is what is going to be put it right there in the HTML. And because of IE's lack of full support for the psuedo hover etc. an anchor is often the best option
3. Yea, that's a wasted piece of code.
4. Without a doubt, document.getElementById should always be tested and used first. document.all and document.layer may be required in some applications. Libraries report users accessing their sites with version 4 browsers and reasonably feel obligate to offer support to those users. Although, I don't know how one tests their code. I've lost my version 4 browsers along time ago.
Browser detection is a must. Sure code that tests for IE or Netscape to use document.getElementById is poorly designed. Object detection is the preferred method. Yet, due to browser bugs occasionally you need to use detection when an object test as available, but doesn't work in a specific browser version. And it is appropriate for fixing CSS bugs. Detection should only be use for known bugs that cannot be handle with object detection.
Somehow I missed innerHTML. Sure it is not standard neither are a few other things, but it sure does a lot simplier job when you need to dynamically replace the content of a div with, say, 5 to infinity tags embedded in an unknown amount of text. This happens when replacing a part of the page using XMLHTTPRequest, response.text or an iframe work around for browsers not supporting XMLHTTPRequest. Parsing that in JavaScript would be both complex and time consumming.
August 16th, 2005 at 8:10 am
Lawrence,
Why? By avoiding any of these your code will be maintainable, and non-JavaScript environments get a workable site, sounds like a win to me. You are right if the idea is “make your site perfect in every browser” not “for the largest possible user number”.
Is it more accesptable to only fix a CSS issue when JavaScript is available, and keep the maintenance of the look and feel rather than in one document in five different ones for every browser? I doubt it. I am not a fan of CSS Hacks, but I rather keep the fixing and the designing in one document than scatter it about. This spells desaster when working in large distributed environments with different skillsets.
And doubles maintenance as you need to update the menu in two spots. Sorry, but this is a really outdated example. Nearly every dynamic menu released in the last years uses a plain HTML menu and enhances that one when JS is available, if you double your efforts then your JS is just not cleverly designed. And how can you define JavaScript enabled as a more likely situation than he other? Even clients who do not care about accessibility care about search engines. If your menu is dependent on JavaScript, those get blocked out, too. Furthermore you cannot do an automated search for broken links, and you cannot spider your page with an internal search engine or reporting tool. This makes your QA more time consuming and expensive.
August 19th, 2005 at 3:47 pm
I enjoyed the article and found it educative. Thank you.
(And also I consider the author knows how to handle anti-social hecklers well.)
August 23rd, 2005 at 8:18 am
regarding noscript:
If I have either a horizontal menu which submenus drop down from
as in
menu1 menu2 menu3
item
item
item
or a vertical menu in which submenus slide out
as in
menu1–item
item
menu2 item
menu3
how can I do it via the unobtrusive method? I don’t think it can be done.
The reason is that the unobtrusive method would fall back on the default rendering of the elements, which is a combination of the markup and the styling.
To fall back on the default rendering of these menus would make for some damn unreadable sites.
September 9th, 2005 at 2:06 am
You ought to read this:
I think that says it all – except that you often don’t even need JS. And any non-CSS reader just parses the basic, unstyled, vertical <ul> or <ol>. And to challenge Bryan’s last post, isn’t that surely one of the most accessible-for-all methods that is possible? All you have to do is make sure the CSS is ignored for things that mess it up, and you’ll have a very readable – if occasionally rendered quite basic – list, regardless. (Also, it solves the problem of having to make some content explicitly visible again to non-JS browsers – if you cut it out (almost; see below) entirely, only browsers that parse the CSS will hide it in the first place).
(And for it to be IE compatible, of course, there’s a much better replacement bit of Javascript at
var mybody=document.getElementsByTagName("BODY").item(0);
var f = document.createElement("FORM");
in1 = document.createElement("input");
in1.type="text";
f.appendChild(in1);
mybody.appendChild(f);
in1.setAttribute("name","myinput");
in1.setAttribute("value","myinputvalue");
f.setAttribute("name","myform");
//returns "myform" value in IE/Fireforx
alert(document.forms0.name);
//works in Firefox/Konqueror only
alert(document.myform);
alert(document.myform.myinput.value);
I’m surprised that
document.formNameworks at all, especially in Firefox et al. It’s better to use either an ID attribute with the same value as the name; or, if you’re not concerned about targetting specific forms with CSS (which is unlikely, unless you’re “homing in” on its children with IDs/classes instead), justdocument.forms['formName'](you must know that you can refer to a property as a string, right? You could even dodocument.forms.formNameas such, but I prefer to use the array method. Either way, you’re not limited to a numerical index).document.getElementByNameis even available in some browsers, but I don’t see the point of that when there are other ways that are easier and much more widespread.Also, if you’re not going to use the corresponding
element.getAttribute()method, why do you bother with the (currently, it seems) unnecessary burdon of typing.setAttribute()? I like to let my laziness free in this area – why use one method to set an attribute that’s automatically assigned as a property of the JS object; especially when you then go on to read the value from it anyway?September 9th, 2005 at 2:11 am
Oh and btw Anton, surely
document.bodyis perfectly valid, anyway? It certainly saves typing outdocument.getElementsByTagName('body')[0]– which is why most people use it…December 3rd, 2005 at 11:11 am
I don’t see why noscript is no longer needed, it saves allot of time.
December 6th, 2005 at 2:45 pm
I have to disagree about the ‘href=’Javscript:’ thing. I normally use the onClick event around a piece of text, but sometimes it’s nescesarry for the mousecursor to automatically look like a hand when the user goes over the link. In Firefox (all versions) the css tag for the ‘cursor: hand;’ does not work so the link will not look like a link. Using ‘void’ or ‘#’ fixes that problem, as the link is recognized as a link by the browser.
I like code-purism as much as the next guy, but in this instance it was impossible to use a simple link.
December 8th, 2005 at 1:50 am
Bas, there’s no “hand” value for the “cursor” property. Use valid CSS and it’ll work in Firefox.
December 13th, 2005 at 12:07 pm
In fact, the “hand” is not the standard property for “cursor”, u may use “pointer” instead.
http://www.zeali.net/blog/entry.php?id=62
December 17th, 2005 at 6:23 pm
The suggestion of replacing noscript with an “enter” page that checks functionality replaces something you don’t like – noscript – with something other people don’t like – enter pages. It also means you’ve added to the maintenance load for the project. It may make sense if you charge by the page, but not if you charge by the hour.
Personally, I like having a notice along the lines of “You can improve functionality by enabling javascript”. A simple noscript tag does that quite well. Replacing it with DOM manipulation means you have to write the JavaScript to do that, and it puts content in your JavaScript, instead of in your HTML. So once again, you are creating extra work in the name of “purity”.
These don’t seem like good tradeoffs to me.
December 20th, 2005 at 4:04 pm
<a href=”javascript:…”>…
Although I agree we should try to avoid this, I feel there are still cases where it applies.
Case in point:
I’ve created a widget, that is multi-paned (sorta like a tabset (all DOM generated))
To enable keyboard navigation, each pane, can be accessed by “tabbing” through each pane, pressing “enter” on the desired pane. (user can also use mouse of course)
Now, to enable the keyboard nav, each “item” must either be a form element (undesired!), or a link <a href=”…”/> The href attribute, is required by the Browser(*), or the navigation won’t work, but of course I don’t want the link to actually go anywhere, thus the attribute is set to:
<a href=”javascript:;”>Pane B</a>
With event handlers attached to deal with the keyboard and mouse nav.
Now, if someone has a brilliant solution to avoid this, great! (I hate the statusbar rollover text anyway), but if not, I don’t see this “no-no” as off the table yet.
Thanks,
Steve
December 20th, 2005 at 4:45 pm
Steve, this is part of almost every DOMScripting tutorial out there..
The first step is to generate links that only work with JavaScript via JavaScript (createElement). Then you set the href to #, or – even better – link them to a real target that makes sense and instruct the script that gets applied via the handler NOT to follow the link by ending it in return false in DOM1 or use a bespoke stopPropagation function in DOM2. Safari, however does not really follow the common ways to stop from following the links and needs an extra onclick return false.
Check the examples in the node cloning post to see what I mean.
For DOM1 instructions, check chapter 3 of the unobtrusive JavaScript course
Opera jumps from link to link via the A key, not tab.
December 22nd, 2005 at 9:05 pm
Chris,
I must still be missing something here then.
whenever I put href=”#” in any link (static or dynamically generated), it scrolls me to the top of the screen… Even if I add return false; to my added eventListener(s).
Edit Yes, you do. The return false must be in the function that was added via the event listeners. It might be more helpful to give a URL and check if there are other errors.
February 13th, 2006 at 1:32 am
Nice write up. I am new to javascript and am going to keep your points in mind when I code.
But here is the problem I am facing. I have an onclick event handler for an anchor element (its a menu) but I dont want the onclick event handler to be invoked by pressing enter. Since all the methods suggested here to make the anchor accessible (href=javascript:;, href=javascript:void(null), href=#) seem to reset the focus on the address (in IE atleast). I can catch the event through onkeypress handler adn check for a enter key and return false, but somehow the onclick event is being invoked after the onkeypress event even if I return false in onkeypress. and by the time it reaches the onclick event the keycode is lost. so, is there a way to prevent firing of onclick event from within onkeypress event?
Thanks
March 17th, 2006 at 7:28 pm
Mostly we don’t need stupid websites like this telling us what is no longer needed. Worry about some idiot using some wacked browser that doesn’t support javascript is a waste of time.
If you’re using a browser that doesn’t support javascript, go back to the early 90’s and stay there.
March 18th, 2006 at 12:51 am
Enzo: Why stop there? I think we should check for purity of blood, a valid credit card, at least 1200 resolution, a 3D card and 2GB of RAM before we allow anyone to read what we put on the web.
(may contain sarcasm)