HTML ids Are Global
Level: Beginner
Normally, when you need to refer to elements in the DOM, you’ll access said elements through methods like getElementById()
or querySelector()
. What you may not know is that if an element has an id attribute, that id value may also be used as the name of a global variable which can also be used to refer to that element.
<div id="divId"></div>
<script>
console.log(divId); // <div id="divId"></div>
console.log(divId === document.getElementById('divId')); // true
</script>
Some HTML elements will do the same with their name
attributes. These elements include <embed>
, <form>
, <img>
, and <object>
.
<img name="imgName" />
<script>
console.log(imgName); // <img name="imgName"></div>
</script>
If multiple elements have matching name
or id
attribute values (bear in mind that ids should always be unique), the respective global with be a live HTMLCollection of each matching element.
<div id="tagged"></div>
<img name="tagged" />
<script>
console.log(tagged); // HTMLCollection [<div>, <img>]
</script>
The global object in browsers is already a crowded place. It contains all of the core language built-ins, all of the Web API built-ins, all of the properties of the window, any definitions of your own added to the global scope, and now potentially all of the ids and some names of elements in the DOM. This behavior sounds like its asking for trouble.
The good news is, it’s actually not so bad. These id globals act more like fallbacks if no other value can be resolved by the same name. Built-ins cannot be replaced with these values, nor can your own variables. You’ll only see them when they don’t clash with anything else.
<script>
let myVar = 'variable';
</script>
<div id="navigator"></div>
<div id="myVar"></div>
<div id="divId"></div>
<script>
console.log(navigator); // Navigator {} (builtin)
console.log(myVar); // variable (user-defined variable)
console.log(divId); // <div id="divId"></div>
</script>
While accessing an element by its id global could come in handy when debugging or doing some quick testing, its recommended you always go through a query method to access elements by id. You never know when there could be a conflict that could cause that reference to refer to something other than your element.
<div id="divId"></div>
<script>
document.getElementById('divId'); // Ok
document.querySelector('#divId'); // Ok
divId; // Not recommended
</script>
More info: