Do DOM tree elements with IDs become global properties?
What is supposed to happen is that ‘named elements’ are added as apparent properties of the document
object. This is a really bad idea, as it allows element names to clash with real properties of document
.
IE made the situation worse by also adding named elements as properties of the window
object. This is doubly bad in that now you have to avoid naming your elements after any member of either the document
or the window
object you (or any other library code in your project) might want to use.
It also means that these elements are visible as global-like variables. Luckily in this case any real global var
or function
declarations in your code shadow them, so you don't need to worry so much about naming here, but if you try to do an assignment to a global variable with a clashing name and you forget to declare it var
, you'll get an error in IE as it tries to assign the value to the element itself.
It's generally considered bad practice to omit var
, as well as to rely on named elements being visible on window
or as globals. Stick to document.getElementById
, which is more widely-supported and less ambiguous. You can write a trivial wrapper function with a shorter name if you don't like the typing. Either way, there's no point in using an id-to-element lookup cache, because browsers typically optimise the getElementById
call to use a quick lookup anyway; all you get is problems when elements change id
or are added/removed from the document.
Opera copied IE, then WebKit joined in, and now both the previously-unstandardised practice of putting named elements on document
properties, and the previously-IE-only practice of putting them on window
are being standardised by HTML5, whose approach is to document and standardise every terrible practice inflicted on us by browser authors, making them part of the web forever. So Firefox 4 will also support this.
What are ‘named elements’? Anything with an id
, and anything with a name
being used for ‘identifying’ purposes: that is, forms, images, anchors and a few others, but not other unrelated instances of a name
attribute, like control-names in form input fields, parameter names in <param>
or metadata type in <meta>
. ‘Identifying’ name
s are the ones that should be avoided in favour of id
.
Do browsers support global references to html elements named by id?
Yes, it's universally supported, and it's even now in the HTML5 specification. Automatic global variables are created for every element with an id
(and many others with name
s).
I never rely on it, there are too many other things in the global namespace. But yes, it's defined behavior.
In a comment below you asked what happens when there's a conflict. More in my answer to another question, but there's an order to it. Automatic DOM globals are shadowed by declared global variables, in a couple of different ways. Here's an example:
// `example1` is a DOM automatic global
console.log(typeof example1); // object
console.log("example1" in this); // true
console.log(Object.prototype.hasOwnProperty.call(this, "example1")); // false
// We have both a DOM element with `example2` as its ID and also a
// `var`-declared global; the latter takes precedence
var example2;
console.log(typeof example2); // undefined
console.log("example2" in this); // true
console.log(Object.prototype.hasOwnProperty.call(this, "example2")); // true
// We have a DOM element with `example3` as its ID, a global object property
// with that name, and also a `let`-declared global variable; the latter wins
this.example3 = 42;
let example3;
console.log(typeof example3); // undefined
console.log("example3" in this); // true
console.log(Object.prototype.hasOwnProperty.call(this, "example3")); // true
.as-console-wrapper {
max-height: 100% !important;
}
<div id="example1"></div>
<div id="example2"></div>
<div id="example3"></div>
In what standard is specified that elements with an id also get a global variable?
Its to do with the Document Object Model (DOM), which defines the logical structure of documents and the way a document is accessed and manipulated. it is not best practice and its better to use document.getElementById(); to avoid naming collisions etc.
Here is an example answer in response to this question previously.
Javascript: Why get an element with getElementById(id) when it is still present in js?
why is this so?
Because early browsers did that, and it's now become standardized.
why do we have to even use
getElementById(id)
instead of simply writing id?
Technically, you don't. But beware that the global namespace is really, really crowded. There's a whole bunch of stuff thrown in there. Not just elements with IDs, but certain elements if they have name
s, the browser context by name, etc., etc., which means there can be conflicts. For instance, if you had an element with id="document"
, the automatic global won't be created. The other, conflicting globals can vary by browser. Also, id
values that aren't valid JavaScript identifiers (like id="foo-bar"
) are still perfectly valid id
values, but the automatic global for it (window["foo-bar"]
) is awkward to use.
Using getElementById
specifically looks for an element with that ID1 (not name
, etc.). So it's more contained and reliable.
1 Ignoring bugs in obsolete versions of IE, which failed to constrain it correctly.
Why do dom-elements exist as properties on the window-object?
I am not sure about the historical perspective, but HTML 5 specifies that elements are candidates to be directly exposed as properties on the window
object if they have an id
attribute:
The Window interface supports named properties. The supported property
names at any moment consist of the following, in tree order, ignoring
later duplicates:[...]
- the value of the id content attribute of any HTML element in the active document with a non-empty id content attribute.
The problem with this definition is that it only guarantees that if there is a <div id="foo">Foo<div>
then window.foo
will be defined. It does not guarantee what exactly its value will be (read the spec for the rules on how that is determined; for example, it might return a collection).
So it turns out the answer to "why use getElementById
ever?" is simple: because you can depend on it to return what you expect without needing to take into account the whole document.
id attribute on form element results in global variable
If you mean that it's available in browsers console than it's ok. It's just a way browser trying to ease the pain of writing document.getElementById('test')
. At least it's the case with Chrome. If you open the Chrome console (for example on this page) and just type "sidebar" and hit enter, you'll see that it returns div with id "sidebar".
To answer directly to your question: it's completely normal to use an id on a form (or any other node) for that matter.
Related Topics
Why Don't Self-Closing Script Elements Work
How to Read CSS Rule Values With JavaScript
How to Programmatically Set the Value of a Select Box Element Using JavaScript
Jquery: How to Call Resize Event Only Once It's Finished Resizing
Difference Between Val() and Text()
How to Capture the Right-Click Event in JavaScript
How to Get the Values of Data Attributes in JavaScript Code
How to Increase Browser Zoom Level on Page Load
How to Draw an Inline Svg (In Dom) to a Canvas
Strip HTML from Text JavaScript
How to Know Which Radio Button Is Selected Via Jquery
How to Change the Text of a Span Element Using JavaScript
Dynamically Set Value of a File Input
Refresh/Reload the Content in Div Using Jquery/Ajax