getElementById() in JavaScript: reaching an element by its identifier

getElementById looks an element up by its id attribute: the syntax without a hash, the expected uniqueness, and identifiers exposed as global variables.
3 min read
Believemy logo

It is the oldest way of getting hold of an element, and it has outlived everything else. One identifier, one call, one element.

Its longevity comes from its simplicity: no selector to parse, an internal index kept by the browser, and an intent readable at a glance.


Definition

getElementById takes the value of an id attribute and hands back the element carrying it, or null when no element does. The name goes in on its own, without the hash used by CSS selectors.

JAVASCRIPT
const button = document.getElementById("confirm");
const missed = document.getElementById("#confirm");

console.log(button.textContent);
console.log(missed);   // null: the hash has no business here

The method only exists on document. An element does not own it, which makes sense: an identifier is meant to be unique across the whole page, so there is no reason to restrict the search to one branch.


One identifier, one element

HTML requires that the same id appear only once per document. When the rule is broken, nothing reports the mistake: the method hands back the first element met in document order, and the following ones become unreachable.

  • A class repeats freely, that is its job. An identifier names a single copy.
  • Case matters: cart and Cart are two distinct identifiers.
  • Spaces are forbidden inside an id value, unlike inside a class attribute.


The global variable trap

Browsers expose every element carrying an identifier as a property of window. The following code therefore works, even though no variable was ever declared.

JAVASCRIPT
// <div id="cart"></div>
console.log(cart);   // the element, with no search at all

const safeCart = document.getElementById("cart");

That convenience is a trap. A let declaration carrying the same name, an identifier renamed in the HTML, and the code breaks with no explanation. Always go through an explicit search stored in a const.


Frequently asked questions

Question

How does it differ from querySelector("#cart")?

The result is identical as long as the identifier is unique. querySelector() has to parse a selector before searching, whereas getElementById queries an index directly. The speed gap is negligible on a single call, and the choice mostly comes down to keeping one file consistent.


Question

What about an identifier with an unusual character?

That is exactly where this method takes the lead again. An identifier starting with a digit or containing a dot breaks a CSS selector, which then demands escaping through CSS.escape. getElementById compares strings and never worries about it.


Question

Why does it hand back null when the element is visible?

Almost always because the script runs before the browser has parsed that part of the HTML. Adding defer to the script tag settles the most frequent case. After that, check the exact spelling of the identifier, casing included.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.