50

If I have a <div id='a'> in Chrome then in javascript I can do a.stuff() (it's like as if a is a global variable).

However this does not work with FireFox - I will need to use document.getElementById('a').

What is the correct behaviour here? (according to W3 specs that is)

Also I'm interested in how will Chrome resolve the ambiguity if I have a div with id a yet have a global variable called a too in my script. Is the behavior going to be random and whacky?

And how would an element with id consisting of hyphens ("-"), colons (":"), and periods (".") be translated (ok i know they can be accessed with document.getElementById but how will the browser translate it into the global variable that was representing them)

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Name
  • 741
  • 1
  • 8
  • 8
  • 2
    See also [Do DOM tree elements with ids become global variables?](http://stackoverflow.com/q/3434278/1048572) and [Why don't we just use element IDs as identifiers in JavaScript?](http://stackoverflow.com/q/25325221/1048572) on why this should not be used. – Bergi Sep 01 '14 at 15:42
  • 1
    The answer about HTML5 is [here](https://stackoverflow.com/a/25325330/3075942). In short: yes, it is now standardized, but not recommended by the standard itself. – user Apr 14 '19 at 14:33
  • 1
    The specification is here: https://html.spec.whatwg.org/multipage/window-object.html#named-access-on-the-window-object – marciowb Oct 09 '19 at 19:11

5 Answers5

47

It depends on which spec you read. :)

This behavior is not described by the HTML4 specification (c.f., http://www.w3.org/TR/1999/REC-html401-19991224/struct/global.html#adef-id and http://www.w3.org/TR/1999/REC-html401-19991224/types.html#type-name). However, it was introduced by Internet Explorer and then copied in other major browsers for compatibility. FireFox also displays this behavior, but only in quirks mode (and even then its implementation seems buggy).

The WHATWG HTML spec currently requires this behavior (a bug report requesting it be removed was closed WONTFIX).

Regardless of spec compliance, using the global namespace (i.e., window) for application code is generally considered bad behavior. Consider referencing element IDs using document.getElementById() or jQuery convenience methods (e.g., $("#a")) and using function-scoped variables to avoid introducing new variables into the global namespace.

There is a longer discussion of this behavior on the WHATWG mailing list.

Niall Smart
  • 848
  • 7
  • 10
  • Update: The bug to remove it is now marked RESOLVED FIXED (it only works in quirks-only mode). – SilverWolf Oct 03 '18 at 23:20
  • 2
    Thanks for actually discussing the specs, and the issues around which one to consult. (Seriously, it's refreshing.) Also, some news from the future: "named access on the window object" now also appears in the W3C HTML5.1 and 5.2 recommendations as well as the 5.3 working draft. So, it is a standard at this point, not that I get any joy out of saying so. – johncip Feb 26 '19 at 07:17
  • As @johncip said, it is a "standard feature" now on HTML5. See: https://html.spec.whatwg.org/multipage/window-object.html#named-access-on-the-window-object But you should avoid to use it... – marciowb Oct 09 '19 at 19:10
15

Since very early days, IE has created global variables that reference elements by their name or id attribute value. This was never a good idea, but was copied by other browsers in order to be compatible with sites created for IE.

It is a bad idea and should not be copied or used.

Edit

To answer your extra questions:

...how will Chrome resolve the ambiguity if i have a div with id a yet have a global variable called a too in my script.

In IE (which introduced this behaviour) if a global variable is declared with the same name as an element id or name, it will take precedence. However, undeclared globals don't work that way. It shoudn't take much to test that in Chrome (I have but I'm not going to give you the answer).

And how would an element with id consisting of hyphens ("-"), colons (":"), and periods (".") be translated (ok i know they can be accessed with document.getElementById but how will the browser translate it into the global variable that was representing them)

Exactly the same as any object property name that is not a valid identifier - square bracket notation (i.e. window['name-or-id']).

Lucio Paiva
  • 19,015
  • 11
  • 82
  • 104
RobG
  • 142,382
  • 31
  • 172
  • 209
  • by declared and undeclared globals. you mean with and without the `var` keyword? – Name Jun 17 '11 at 07:00
  • 8
    "shoudn't take much to test that in Chrome (I have but I'm not going to give you the answer" Unhelpful and elitist. For anyone interested, the last declared variable will take precedence. – Polyducks Mar 16 '18 at 11:05
5

Technically, this question is opinion, but it's a good question.

IE does this as well and it has caused headaches for some.

The rules for naming variables in JavaScript and IDs in HTML are different. I can't see how this is a good thing.

For instance, on this page there is an element with an ID of "notify-container". That's not a valid JavaScript name at all.

Also, when are these names bound? If an inline script declares a variable and then the element appears later, which has precedence?

It's cannot be made consistent.

Community
  • 1
  • 1
cgp
  • 41,026
  • 12
  • 101
  • 131
0

The worst thing about using elements this way is that they could break at any time if a new API is introduced that has the same name in the global scope.

For example, if you had this prior to the addition of the Performance API

<p id="performance"></p>
<script>
    performance.innerHTML = "You're doing great"
</script>

Then that piece of code would've stopped working now in recent browsers that implemented the Performance API as a global performance object was added.

Jamesernator
  • 778
  • 7
  • 13
-1

I think document.getElementById is supported by most browsers so far.. Its better and safe using this one..

Philemon philip Kunjumon
  • 1,417
  • 1
  • 15
  • 34
  • 1
    late comment but, getElementById was introduced in DOM Level 1 for HTML documents. It is supported by all browsers that support Javascript. – rlemon Jan 03 '14 at 14:28