Should we use getElementById?

Recently I started thinking about how to explain to someone why we use getElementById. We are always told to use document.getElementById(“someId”) to obtain a reference to a uniquely identified element on the page, but when web browsers give JavaScript global variable access to those id’s, why should we use getElementById?

After all, things work when using the global id too.

<div id="someElement">getElementById works</div>
<div id="anotherElement">This also works?!</div>
var someElement = document.getElementById("someElement");
console.log(someElement.innerHTML); // getElementById works
console.log(anotherElement.innerHTML); // This also works?!

The pros and cons of getElementById

I had trouble coming up with good reasons, and after scouring many articles I was still struggling on how to explain. I found that there exists a lot of mythology about getElementById. Some good, some bad. In the end, I settled on examining the pros and cons of each issue, to make it easier to compare them against each other.

This post also acts as a comprehensive response to the Why use getElementsById thread too.

getElementById informs where the variable was first defined

When we have trouble with an undefined variable, commonly we trace back through the code to find out what happened to it, and where it was first defined.

When the global id is used to retrieve an element and that element isn’t found, it becomes more difficult for us to figure out just what went wrong.

// good
var getElement = document.getElementById("someElement");
console.log(getElement); // <div id="someElement">...</div>
// bad
console.log(missingElement); // Don't know if missingElement was defined elsewhere.

Was missingElement defined at some earlier point in the code? Commonly only an extensive investigation reveals the answer.

With getElementById though, it increases the readability of the code, makes it crystal clear that the variable is being defined there, and also from where we are getting the element.

Using getElementById is a definite positive in this situation.

  • getElementById :white_check_mark:
  • global id :x:

getElementById returns null if id not found

When getElementById can’t find the element, it gives you null instead.

var getElement = document.getElementById("missingElement");
console.log(getElement); // null

Null really shouldn’t be used these days, and was considered to have been a mistake to include it in the language. Developers of programming languages argue about having bottom values like null and undefined at all, and meanwhile JavaScript has two of them. Null misbehaves in JavaScript is seen by typeof mistakenly as an object, for example, and is best avoided.

A few articles that help to give more background on the history and troubles with null are:

What should we do instead of dealing with null? We should check if the element doesn’t exist, and throw an appropriate error.

var getElement = document.getElementById("missingElement");
if (!getElement) {
   throw new ReferenceError("missingElement is not defined");
}

This extra code thought gives exactly the same effect as when not using getElementById.

Because we end up with the same result as when not using getElementById, this one falls in favour of using the global id instead.

  • getElementById :x:
  • global id :white_check_mark:

getElementById prevents uncaught errors if id not found

var getElement = document.getElementById("missingElement");
console.log(getElement); // null
console.log(missingElement); // Uncaught ReferenceError: missingElement is not defined

Using getElementById prevents an uncaught error from occurring. However, it is frequently argued that it’s beneficial to receive such warnings when developing code.

On the other hand many developers don’t check if getElementById was successful. Instead, they just automatically assume that getElementById works.

What should we do about this? Throwing an error should be done when developing code and then removed for production. We can structure things so that in development we have the additional information that we need, and in production, that error handling can be removed.

utils-dev.js

function getById(id) {
    var el = document.getElementById(id);
    if (!el) {
        throw new ReferenceError(id + " is not defined");
    }
    return el;
}

utils-prod.js

function getById(id) {
   return document.getElementById(id);
}

script.js

var getElement = getById("missingElement");
console.log(getElement);

This flexibility of handling errors (or not as you choose) falls in favour of using getElementById.

  • getElementById :white_check_mark:
  • global id :x:

Variables block access to global id

Variables with the same name as the identifier prevent access to the element via the global identifier.

<div id="content">...</div>
var content = "Some content";
// The defined variable blocks the global id access to the element

Using getElementById is the only good way to access the element, which can be done either by itself or preferably, with a function so that we can more appropriately handle errors if it can’t be found.

var content = "Some content";
var getElement = document.getElementById("content");
console.log(getElement); // <div id="content">...</div>

For allowing access to elements blocked by global id, this one goes to getElementById.

  • getElementById :white_check_mark:
  • global id :x:

getElementById allows access to hyphenated identifiers

Identifiers with hyphens in the name aren’t accessible via the global object, as attempting to do so results in a reference error.

<div id="some-element">...</div>
var someElement = some-element; // Uncaught ReferenceError: some is not defined

The hyphen is seen by JavaScript as being a minus sign, resulting in the reference error because it thinks you want to do some math.

It is possible to access the element via the window object with window["some-element"] but that’s considered to be abuse of the global namespace, and is not a good practice to access identified elements.

The best solution here is to use getElementById to retrieve the element.

var someElement = document.getElementById("some-element");
console.log(someElement); // <div id="some-element">...</div>

The hyphen issue puts this one undeniably with getElementById.

  • getElementById :white_check_mark:
  • global id :x:

How does it fare?

Here’s the breakdown of how the different issues relating to getElementById stack up with each other.

Issue with getElementByid   Use it   Avoid it
-------------------------   ------   --------
Defined variables             ✅       ❌
The null issue                ❌       ✅
Uncaught errors               ✅       ❌
Blocking global id            ✅       ❌
Hyphenated identifiers        ✅       ❌

Of all the issues relating to getElementById, using it is by far the better choice to make.

Work smarter, not harder

Because we tend to be lazy (or efficient - the jury is out on this one), we want to benefit from the protection that getElementById grants us, without having to do the error handling every time.

One of the better ways to make this easier, is to use a function to retrieve the elements, so that the details of error handling can be left in one place.

function getById(id) {
   var el = document.getElementById(id);
   if (!el) {
	    throw new ReferenceError(id + " is not defined");
   }
   return el;
}

var someElement = getById("someElement");

Summary

After exploring several issues relating to getElementById the definitive answer is that yes, we should continue to use getElementById.

11 Likes

Never thought to test for the value. I’ll implement that practice. Thanks!

1 Like

I was a bit puzzled by this. Should that 2nd line there be

console.log(header.innerHTML); //getElementByID works?!

As is, it looks like both are being accessed by the global variable. As you’re assigning a value to the variable header but dont then appear to use it.

Thanks Chris, that’s a victim of editing and header should be someElement instead.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.