2012-08-15

DOM: element IDs are global variables

Several tweets mentioned that in order to display an element in Chrome’s JavaScript console, you only have to type its ID. @johnjbarton pointed out that that is because all element IDs are global variables. This blog post explains a few more details.

The standard

The HTML5 standard specifies that the window object must have a property key whose value is elem if...
  • there is exactly one DOM element elem whose property id has the value key.
  • there is exactly one DOM element elem whose property name has the value key. elem’s tag must be one of: a, applet, area, embed, form, frame, frameset, iframe, img, object.
If there is more than one matching element, different rules apply. With this in mind, let’s look at an example. Given an HTML document where a div element has the ID “foo”:
    <div id="foo"></div>
Thus, the div element above can be accessed either via window.foo or, like all properties of window, via the global variable foo. For example, in the Chrome console, you can do the following:
    > "foo" in window
    true
    > foo
    <div id=​"foo">​</div>​

Firefox

Firefox (version 14) works slightly differently.
    > "foo" in window
    false
    > typeof foo  // does the variable exist?
    object
    Element referenced by ID/NAME in the global scope.
    Use W3C standard document.getElementById() instead.

    > foo
    [object HTMLDivElement]
    Element referenced by ID/NAME in the global scope.
    Use W3C standard document.getElementById() instead.
    
    > "foo" in window
    true
What does that mean? Initially, there is no property window.foo. But the first time it is accessed (either directly or via the global variable foo), it is created automatically.

[Note: the code above can only be executed via a script tag, but not via the console. That is because the console handles global variables differently, so that the auto-creation process doesn’t work properly.]

Whenever you read foo, the div element is returned and a warning tells you not to do that. Obviously, the warning is correct: It’s fine to use this feature interactively, but you should not rely on it in actual code.

Updates

Update 1: Cody Lindley has written a jsPerf test comparing the performance of accessing foo via a global variable versus via window.foo. Interestingly, Firefox is the only browser where window.foo is faster.

Update 2: Commenter tjvantoll mentions where HTML5 standardizes that element IDs become properties of window. In reaction to that, the post now describes what is specified there.

No comments: