Feed Sign in with OpenID OpenID

Simon Willison’s Weblog

Don’t use document.all

I’ve lost count of the number of Javascript scripts I’ve seen floating around that include the equivalent of the following code snippet:

if (document.all) {
   element = document.all[id];
else {
   element = document.getElementById(id);
}

document.all was introduced in Internet Explorer 4, because the W3C DOM hadn’t yet standardised a way of grabbing references to elements using their ID. By the time IE 5 came out, document.getElementById() had been standardised and as a result, IE 5 included support for it.

IE 5 was released in September 1998. A popular browser statistics site (insert usual disclaimer as to the reliability of any stats but your own here) show IE 4’s market share to be in the region of 1%. Even Netscape 4 has more users than that!

Don’t use document.all. document.getElementById() is supported by every Javascript supporting browser released since 1998.

This is Don’t use document.all by Simon Willison, posted on 11th August 2003.

View blog reactions

Next: Moveably Type with XSLT

Previous: Self-contained data: URI kitchen

49 comments

  1. Hear, hear! I found it so much easier to pickup javascript/DHTML when I relaized this. Now I don't have to do this. I have also found that to a very large degree, javascript as a whole as standardized as many browser-specific nuances as there used to be. Aaron

    Aaron Brazell - 11th August 2003 18:51 - #

  2. Damn my typos. This is what happens when my mind works faster than my fingers. Aaron

    Aaron Brazell - 11th August 2003 18:52 - #

  3. Why are "IE" and "DOM" underlined? To me, underlines on the web mean links.

    Fred Jackson - 11th August 2003 19:09 - #

  4. They are underlined in Mozilla because they are marked up as acronyms; hover your mouse over them and their expanded form comes up as a tool tip. This is the default style for that tag as governed by the browser - IE doesn't highlight them at all. I see your point about a potential confusion with links but underlining acronyms is becoming quite common (at least in technical blogs) and I haven't yet seen a better way of visually distinguishing them from other content.

    Simon Willison - 11th August 2003 19:18 - #

  5. Poor man's getElementById for IE4 compatibility with simple scripts:

    var ie4=document.all && !document.getElementById;
    if(ie4) {
        document.getElementById = new Function('var expr = /^\\w[\\w\\d]*$/, elname=arguments[0]; if(!expr.test(elname)) { return null; } else if(eval("document.all."+elname)) { return eval("document.all."+elname); } else return null;')
    }

    Owen - 12th August 2003 03:23 - #

  6. Minor point: some (all?) versions of IE don't support document.getElementsByTagName('*'), so if you want an array containing every node from a DOM tree, and you want it work in IE you still need to make use of document.all.

    paul hammond - 12th August 2003 10:51 - #

  7. Great point Paul, I'd forgotten about that. There's still no reason to use it for accessing elements by ID (unless IE 4 support is essential for some legacy intranet reason).

    Simon Willison - 12th August 2003 10:53 - #

  8. You can overwrite the existing getelementsbytagname function with one that works with '*':

    function ie_getElementsByTagName(str) { if (str=="*") return document.all else return document.all.tags(str) } if (document.all) document.getElementsByTagName = ie_getElementsByTagName

    Shamelessly stolen from siteexperts http://www.siteexperts.com/tips/contents/ts16/page 3.asp?main=on ;)

    Martijn - 12th August 2003 18:01 - #

  9. about those acronyms..

    use css to style them to look the same in IE, and make them subtle with some light gray border, and/or even dashed/dotted?

    (and change a mouse pointer -- php.net does this ;)

    acronym {
    border-bottom: 1px dashed #999;
    cursor: help;
    }

    zombie - 12th August 2003 18:38 - #

  10. sorry. that is better with:

    border-bottom: 0.1em dashed #999;

    zombie - 12th August 2003 18:39 - #

  11. Even better: kill JavaScript altogether. It's an arrogant and ignorant pig!

    Tom Morris - 13th August 2003 01:03 - #

  12. I'd have to disagree there; I've been playing with Javascript quite a lot recently and you can do some really cool stuff with it - for example, using it to enhance the user interface of a web application by allowing dynamic re-ordering of a list of elements.

    Simon Willison - 13th August 2003 02:06 - #

  13. Sorry Tom, but JavaScript can do some funky, and more importantly, useful stuff. I go for the philospophy that you should never build your site to rely on JavaScript, but there's no harm in little add-ons that enhance experience. For example, why use alert boxes to point out which box on a form is empty, when you can do a little DHTML to change the page instead. Really cool trick and it's more usable too.

    Andrew Bowden - 13th August 2003 09:41 - #

  14. Okay, you win. I just get a bit pissed off with it occasionally. I do use it for popup windows and such, and to auto-fill boxes with values. It's useful, but I still think it's a pig to get right.

    Tom Morris - 13th August 2003 19:07 - #

  15. Shameless plug... but http://www.metalusions.com/backstage/articles/8/ is a little article I wrote on this subject a while back. Comments would be appreciated.

    dave - 11th September 2003 19:15 - #

  16. I'm doing some work with popup calendar using javascript and I tried the check that dave had in his article:

    if(document.all && !document.getElementByID) {

    alert("document.all supported\ndocument.getElementByID not supported");

    }

    I'm using IE6 and for some reason this alert always pops up. I can't figure out why document.getElementByID would not be supported by IE 6. Any suggestions? Thanks.

    Matt - 15th September 2003 16:49 - #

  17. Yes - you've got the case wrong. If you test for document.getElementById it works fine. In any case, unless you absolutely have to support IE 4 (which has a market share statistically approaching zero) you should forget document.all even exists and just use document.getElementById.

    Simon Willison - 15th September 2003 17:11 - #

  18. document.getElementById is case-sensitive. It is not document.getElementByID

    loufoque - 16th November 2003 21:00 - #

  19. I'm afraid, for the purposes of compatibility we'll have to stick to that old compat switch some more.. E.g. in Mozilla 1.4.1 the document.getElementById() doesn't work and will never. AFAIK, the getElementById is IE stuff and really doesn't belong into JavaScript, it's more JScript.

    R. MacAran - 11th December 2003 17:17 - #

  20. "I'm afraid, for the purposes of compatibility we'll have to stick to that old compat switch some more.. E.g. in Mozilla 1.4.1 the document.getElementById() doesn't work and will never. AFAIK, the getElementById is IE stuff and really doesn't belong into JavaScript, it's more JScript."

    getElementById has worked in Mozilla for years and still does, it's W3 DOM not 'IE stuff'.

    Dave - 23rd February 2004 23:49 - #

  21. What if I wanna get multiple objects in the page? e.g.,

    var checkBoxes = document.getElementById('CheckBox');
    // I have more than one object named "CheckBox" in the page, I am suppose to receive an array.
    var numberTables = checkBoxes.length;
    //numberTables return 'undefinded'

    Help please.

    Lee - 22nd March 2004 22:45 - #

  22. IDs should be unique for the page on which they are used. To grab all check boxes, use something like this (untested):

    var inputs = document.getElementsByTagName('input');
    var checkboxes = [];
    for (var i = 0; i < inputs.length; i++) {
      if (inputs[i].type == 'checkbox') {
        checkboxes.append(inputs[i]);
      }
    }

    Simon Willison - 22nd March 2004 23:02 - #

  23. What should I do if I had a list of over 200 elements and I wanted to access one of them? Is it still a good idea to give each one of them an individual id? Thanks.

    Matt - 2nd April 2004 22:47 - #

  24. Okay - interesting thread on the deprecation of document.all .... I have a question - can I use Jscript, JavaScript or anything else to dynamically change the class in a TD tag? I have menu items in TD elements of a table that I want to have the color change when clicked ( I have an 'a'nchor ) element that takes the user to the URL/URI. Is it do-able? Thanks all ....

    dgretlein - 21st May 2004 05:59 - #

  25. hello Simon, Great weblog you have here. i'm learning a lot, especially the php/js spellchecker article was great. now my question is: what's so bad about code snippet you're crisizing? is it that 1% of all browsers (that's, ie4) is relying on it; while leaving it out may enhance the performance of a script? or is it that it may produce errors on non-IE browsers nowadays?

    jeroen schellekens - 16th June 2004 21:22 - #

  26. It's superfluous code. Just using document.getElementById(id); has exactly the same effect. I'll take the one line version over the longer version any day. IE4 support just isn't an issue any more.

    Simon Willison - 16th June 2004 21:52 - #

  27. One difference between document.all[] and document.getElementById() - the first returns _all_ the elements that match the specified criteria and the second only the _first_ of them. So if you have

    {div id="menuitem"}...{/div}

    {div id="menuitem"}...{/div}

    (here '{' and '}' mean the symbols for 'less than' and 'greater than' but this stupid form doesn't allow you to enter arbitrary text - it doesn't escape your input and you cannot enter certain tags)

    and you want to select all "menuitem" elements for some reason (i.e. iterate on them) you probably just do document.all["menuitem"] for IE but in Mozilla you can't substitute it with document.getElementById("menuitem"), because it will return not a collection but only the first menuitem.

    There exists document.getElementsByName("menuitem"), which will return all elements with name "menuitem" but what you really want is to select by ID, not by name. It's a pity that there is not document.getElementsById("menuitem") (just an 's' more after getElement) to return all elements.

    In fact IE does this by document.getElementsByName() - this method works either for name and for ID - but this is true only in IE not in Mozilla - in Mozilla work only for name (as it is in the w3 standard).

    Stan - 1st July 2004 15:17 - #

  28. Stan,

    If you check the W3C documentation, you'll see that IDs are supposed to be unique within a page. In other words, you should not be using multiple div's with the same ID, that what CSS classes are for. That's why there is no 'getElementsById' but instead we have 'getElementsByName' which, "Returns the (possibly empty) collection of elements whose name value is given by elementName.". Hope this helps.

    Jason - 9th July 2004 16:06 - #

  29. >> It's a pity that there is not document.getElementsById("menuitem") @__@ ????? ID is supposed to be unique. It is a shame if there is document.getElementsById("menuitem")

    CC - 8th October 2004 21:10 - #

  30. In response to dgretlein's post, to change the css class using javascript, try the following:

    theElement.css = (theElement.style) ? theElement.style : theElement;
    theElement.className = "nameOfCssClass";

    Gareth - 24th October 2004 06:18 - #

  31. However it is frustrating that there isn't a getElementsByClass("classname") that would return all elements with class classname.

    Troff - 18th May 2005 15:33 - #

  32. you can create your own 'getElementsByClass()' function... if you can read French, this helpful article shows you how. Even if you can't read French, you should be able to follow the code... you might even learn some French while you're at it! I modified my version to take a tag parameter as well so I could specify divs of a particular class, etc.

    Cailean - 1st June 2005 05:29 - #

  33. not satisfied. once i started working with document.getElementById, it didn't work. then i tried with doucument.all. it is working fine with it. latter i checked both. both r working fine. i didn't understand why it didn't work in the first time. pl. mail me if u know.

    Murty - 1st June 2005 12:51 - #

  34. This article misses some important points. The recommend document.getElementById does not get you html nodes that do NOT have an ID. Other alternative methods require a NAME attribute. For this reason, you certainly see document.all around quite a bit yet. As a sample scenario, imagine you want to dynamically disable all user interaction with any node NOT within a specified node (container). You have to null reference onmouseover, onmousedown events as well as anchors.. Now imagine there is a TD with an onmouseover attribute, but no ID or Name(common in many dhtml menu controls). You still need document.all to access every bit of html even if it doesn't have an id or name attribute.

    KarlB - 7th July 2005 19:14 - #

  35. KarlB: That's what document.getElementsByTagName (and the other DOM standard navigation methods, such as element.children, element.firstChild etc) are for. document.getElementsByTagName('*') will give you all of the elements on a page.

    Admittedly, this doesn't work in older versions of IE - in which case you have to fall back on document.all. That's the only case in which it should be used, and you use it like this:

    var elements = document.all ? document.all : document.getElementsByTagName('*');

    To ensure compatibility with non-broken browsers.

    Simon Willison - 7th July 2005 20:29 - #

  36. I read all the way through these comments hoping someone would mention an alternative to something I came across in IE specific code. Hopefully I'll find the answer sooner or later, but the code was iterating through elements with x and checking if x index's ID had a particular name, so:

    for (x=0; x<document.all.length; x++) if(document.[x].id=="textanimlink")

    Any ideas on a simple way to convert this to work in non-IE browsers (FireFox)?

    Mardeg - 29th July 2005 20:42 - #

  37. Excuse me by my poor english, the document.all is something important because is the unique maner for get a reference given a index (ej. sourceIndex) i need this for pass the name for an input set between pages. Someone have idea from make this in firefox?

    Gustavo Gonzalez - 29th July 2005 22:28 - #

  38. seems to be a lot of confusion here. ID is just that ID for example if you wanted to GUID a form in your HTML document you would do so on ID so a valid ID might be \applications\myapp\forms\form_customer as a relative ID or a complete url or a long Integer in any event the id should conform to the namespace you need the name of the form is only the name just as the name of a file doesnt include the folder but when folder and file are combined you get a path or ID :) there is a need to be able to get ALL or filtered for example nothing wrong with document.getElementsByWidth(x) which would equal document.all where with = x Just pointing this out because many seem confused. Any query (regardless of language or context) has a base and the base is ummm ALL or that is (all that is) All isnt something microsoft made up all is something the other hard coders ignored. :)

    timbuck - 6th December 2005 05:03 - #

  39. i agree

    mamo - 4th January 2006 19:16 - #

  40. So, uh, I just got assigned a project which HAS to be IE 4 compatible...ugh...

    Greg Hinch - 3rd February 2006 02:16 - #

  41. Hi i used document.getElementsByName() which is well working in IE but it is not working in FireFox. can you please tell me a method same working function as getElementsById which can be used for FireFox. thank you

    sonali,BTech 2001 - 29th March 2006 08:20 - #

  42. Hi i used document.getElementsByName() which is well working in IE but it is not working in FireFox. can you please tell me a method same working function as getElementsByName which can be used for FireFox. thank you

    sonali,BTech 2001 - 29th March 2006 08:23 - #

  43. Does anyone why document.getElementById returns true but document.getElementById("advertisementText") is said not supported on IE6 (javascript error)? Thank you!

    Sharon Tam - 13th April 2006 02:06 - #

  44. someone help me. I can't figure out how to post something that has more than one line. This thing wont do any of the work.

    Volte - 2nd May 2006 03:39 - #

  45. Hey, I've been googling for days for solutions of this, very little information out there, this is by far the most informative. Ironically I started making my own function for getElementsById, and getElementsByClass (because, I tried that getElementsByName, doesnt work the way you think it does, that actually gets elements with the tag name.) So, in the name of science, programming, and furthering out knowledge, I'll share my code, its not complex, but its efficient. Works in Safari, and Firefox. Not sure about the other browsers. I don't have Internet Explorer, someone will have to test that POS.

    document.getElementsById = function (tagName) {
    	var unFiltered = document.getElementsByTagName('*');
    	var filtered = [];
    	for (i = 0; i < unFiltered.length; i++) if (unFiltered[i].getAttribute('id') == tagName) filtered.push(unFiltered[i]);
    	return filtered;
    }
    
    document.getElementsByClass = function (tagName) {
    	var unFiltered = document.getElementsByTagName('*');
    	var filtered = [];
    	for (i = 0; i < unFiltered.length; i++) if (unFiltered[i].getAttribute('class') == tagName) filtered.push(unFiltered[i]);
    	return filtered;
    }

    Volte - 2nd May 2006 14:21 - #

  46. Try booking a room at www.harrahs.com. They use document.all in the script that submits the final registration form, and it fails in all my browsers except IE.

    Nick Linnear - 2nd May 2006 19:43 - #

  47. This is the browser trap I use for testing DOM compatibility
    if (document.layers) {
    	type="NN";
    } else {
    	if (document.all) {
    		if (document.getElementById) {
    			type="IE5+";
    		} else {
    			type="IE4";
    		}
    	} else {
    		type="FF";
    	}
    }

    Danny Bishop - 4th May 2006 01:40 - #

  48. Hi, I am having some trouble with javascript. I am trying to dynamically change some text in between a td tag and also trying to dynamically change values in an drop down list box. Everything works fine in FireFox. The values change in both IE and FireFox but the text in between the td tag does not in IE. I did an alert popup to see what was returned whan I did document.getElementById("postal") and IE gave me [object] while FireFox gave me [object HTMLTableRowElement]. The error message in IE is "Object doesn't support this property or method". My site is http://olie.getmyip.com:8080/Exxtensions/ and then click on register on the top. Like I mentioned before, FireFox works just fine, but IE is giving me problems. The desired result would be that of FireFox in IE. Any help would be appreciated.

    Oliver Kiss - 26th May 2006 04:53 - #

  49. An important note for Windows Mobile 2003 developers... The version of IE on Windows Mobile 2003 is IE 4, minus the VBScript. As such, 'document.all' is useful as 'document.getElementById' is absent!

    Justin Megawarne - 11th September 2006 12:08 - #

Comments are closed.

Previously hosted at http://simon.incutio.com/archive/2003/08/11/documentAll

A django site