Do Dom Tree Elements With Ids Become Global Properties

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’ names 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 names).

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 names, 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



Leave a reply



Submit