Javascript & DOM Order: getElementById() is 'null'

Just a gentle reminder: looking to modify an element on the page using JavaScript's getElement or querySelector? Make sure your script appears further down the DOM than the element you're trying to change!

I have a feeling this a pretty basic concept in JavaScript, but for those of us who come to the language with a "fake it until you make it" kind of mentality, sometimes you need a simple reminder. Today isn't the first time I've hit this wall. I target a page element to affect some sort of change and JavaScript seems to bug out. Even though the element obviously exists--there's no mistake in the element ID--the console reports an error all the same: i.e., document.getElementById("some-target") is 'null'. There's more than one way to get this kind of result: your console will spew a similar disclaimer at you if you somehow manage to implement the same script twice on the same page (sometimes a risk in responsive design). If you're getting this kind of error, however, one of the first things you should check is the placement of your JavaScript: does it come before or after the element you're trying to target?

It's a pretty simple concept, if your script comes before the element it's looking to affect, the element won't yet exist when the script loads. It's like reading the first line of a message as it comes through a fax machine; if it references anything further down the page, you'll have no clue what it's about--it won't compute.

There are a couple of solutions to this. One is, of course, to place your script below the element it's looking for. The other option is to tell your script exactly when to go looking for the element. You might do that in any of the following manners:

document.addEventListener("DOMContentLoaded", function() { 
  var target = document.getElementById("some-element"); 
  // ...and some other stuff... 
})

window.addEventListener('load', function() { 
  var target = document.getElementById("some-element"); 
  // ...and some other stuff...
})

window.onload = function() { 
  var target = document.getElementById("some-element"); 
  // ...and some other stuff...
}

Personally, though, in 2021, on Firefox 90, I feel that all of these methods allow for too much painting of the DOM for it to be more effective than simply placing your script below the element it's looking for--depending on what you intend to do. If, for example, you were using the presence of a cookie to display or not display an element, you'd really not like for that object to get painted in the DOM and then suddenly disappear because JavaScript finally caught up to this illusive concept of "load". This doesn't really matter for elements that are below the fold, but for anything above the fold, it can mean that users see a "flash" of content before JavaScript helps style it.

Whatever method you choose, it's always best to remember that web pages are actually rather dumb. They can be lightning fast, yes--but, they're basically a fax on speed.