JavaScript DOM selectors: querySelector, getElementById, and more

JavaScript DOM selectors: querySelector, querySelectorAll, getElementById, getElementsByClassName, getElementsByTagName, live HTMLCollection vs static NodeList. Snippets use `{run=false}`—inject the sample HTML in a browser or with happy-dom/jsdom.

Published

Updated

Read time 5 min read

Reviewed byDeepak Prasad

JavaScript DOM selectors: querySelector, getElementById, and more

DOM selector APIs locate elements in the rendered document so you can read state, attach listeners, or mutate markup. The classic entry points are getElementById, getElementsByTagName, getElementsByClassName, querySelector, and querySelectorAll (MDN Web Docs). When you already think in CSS strings, the dedicated querySelector and querySelectorAll guide on this site walks through return types and static vs live collections.

Tested on: Snippets assume a real document with the sample HTML below. Fences use {run=false} for the site runner; copy into DevTools or load the same markup with happy-dom / jsdom locally.


Quick reference

Goal API
One element by id document.getElementById('id')
Many elements by tag document.getElementsByTagName('div')
Many elements by class document.getElementsByClassName('class')
First match for a CSS selector document.querySelector('div.item > a')
All matches for a CSS selector document.querySelectorAll('.item')

Sample HTML used in the examples

The snippets below assume this markup (save as HTML or build the same tree in tests):

html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>DOM Selector</title>
    </head>
    <body>
        <h1 class="special">JavaScript DOM Selector</h1>
        <p class="special">
            These are built-in methods that are provided within JavaScript
        </p>
        <div id="first">
            <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Optio,
                laudantium corporis possimus eveniet a pariatur! Fugiat,
                laudantium cupiditate deleniti nisi beatae repellat ad porro
                debitis aliquam suscipit rem optio odio!
            </p>
        </div>
        <div id="second">Another Lorem Ipsum, wow</div>
    </body>
</html>

In the browser, document refers to the loaded page. The examples assume that tree is already parsed so javascript dom select calls resolve to real nodes.


getElementsByTagName (javascript get element by type)

document.getElementsByTagName(tagName) returns a live HTMLCollection of every element with that tag in document order. It is the usual answer when people mean javascript get element by type in the sense of “all div nodes” rather than an input’s type attribute.

javascript
const divs = document.getElementsByTagName('div');
console.log(divs.length);

You should see 2—the two wrapper div elements in the sample.

HTMLCollection values are array-like (indexes and length), not real arrays—convert with Array.from(nodes) if you need array methods.

To read the markup inside the first div:

javascript
const lorem = document.getElementsByTagName('div');
const content = lorem[0].innerHTML;
console.log(content);

You should see a multi-line string that starts with whitespace and a <p> tag containing the “Lorem ipsum…” paragraph from #first.


getElementById

document.getElementById(id) returns a single Element or null. IDs should be unique in valid HTML.

javascript
const secondDiv = document.getElementById('second');
console.log(secondDiv.innerText);

You should see one line: Another Lorem Ipsum, wow.


getElementsByClassName (dom selectors in javascript by class)

document.getElementsByClassName('class') returns another live HTMLCollection. Class tokens must match one of the element’s classes (no leading dot in the string).

javascript
const specials = document.getElementsByClassName('special');
console.log(specials.length);

You should see 2 (h1 and p both carry special).

javascript
const special = document.getElementsByClassName('special');
const secondElem = special[1].innerText;
console.log(secondElem);
special[0].style.color = 'red';
console.log('style.color', special[0].style.color);

You should see the paragraph’s visible text (trimmed by the engine), then style.color red after mutating the first .special node (h1).

special[0] is the first .special node (h1 here); special[1] is the paragraph. In a real browser, setting style.color updates the rendered heading color.


querySelector (javascript get element by selector)

document.querySelector(selector) takes a CSS selector string and returns the first matching element, or null. Use #id, .class, tag, and combinators such as div p for descendants.

javascript
const paragraph = document.querySelector('p');
const special = document.querySelector('.special');
const firstID = document.querySelector('#first');
const divP = document.querySelector('div p');

console.log(paragraph.innerText);
console.log(special.innerText);
console.log(firstID.innerText);
console.log(divP.innerText);

You should see four lines in order: the first p in the document (inside #first), then the h1 text (first .special in tree order), then the combined text inside #first, then the nested div p paragraph again—paragraph and divP overlap on the same node here.

Because querySelector('.special') walks the tree in document order, the first .special match is the h1, not the paragraph—compare paragraph vs special in the output above.


querySelectorAll

document.querySelectorAll(selector) returns a static NodeList of all matches. Lengths often mirror getElementsBy* counts, but the collection does not update automatically when nodes are added or removed.

javascript
const paragraph = document.querySelectorAll('p');
const special = document.querySelectorAll('.special');
const firstID = document.querySelectorAll('#first');
const divP = document.querySelectorAll('div p');

console.log(paragraph.length);
console.log(special.length);
console.log(firstID.length);
console.log(divP.length);

paragraph[1].style.width = '250px';
console.log('paragraph[1].style.width', paragraph[1].style.width);

You should see lengths 2, 2, 1, and 1, then paragraph[1].style.width 250px after styling the second p (the .special paragraph).


Live HTMLCollection vs static NodeList

  • getElementsByTagName / getElementsByClassName: live collections; changes to the DOM can change length and indexed entries while you hold the reference.
  • querySelectorAll: static NodeList; it represents the matches at call time.

For new code, many teams prefer querySelector / querySelectorAll because CSS selectors stay familiar and compose well across components. For more on selector strings and return types, see JavaScript querySelector and querySelectorAll.


Summary

Prefer getElementById when you have a stable id; use querySelector / querySelectorAll for CSS-shaped queries; remember live vs static collections when you cache node lists.

getElementById is the fastest mental model when you truly have a unique id. getElementsByTagName and getElementsByClassName return live HTMLCollection objects that update as the DOM changes. querySelector returns the first CSS match or null, while querySelectorAll returns a static NodeList of every match—remember the first-vs-all distinction when debugging “missing” nodes. Always guard for null, avoid caching live collections if siblings will be added or removed while you still hold the reference, and continue with JavaScript querySelector and querySelectorAll when you want a deeper walkthrough of the CSS-driven APIs alone.


References


Frequently Asked Questions

1. What is the difference between querySelector and querySelectorAll in JavaScript?

querySelector returns the first Element that matches a CSS selector, or null. querySelectorAll returns a static NodeList of every match.

2. Is the NodeList from querySelectorAll live?

No. querySelectorAll returns a static NodeList snapshot. getElementsByTagName and getElementsByClassName return a live HTMLCollection that updates when the document changes.

3. How do I get an element by CSS selector in JavaScript?

Use document.querySelector for the first match or document.querySelectorAll for all matches. Scope with element.querySelector from a known parent when you want to search a subtree.

4. How do I get elements by type in JavaScript?

HTML type usually means tag name: document.getElementsByTagName('input'). For input kinds, use a CSS selector such as document.querySelector('input[type=checkbox]').

5. Why does querySelector('.myclass') not return all elements with that class?

querySelector only returns the first match in document order. Use querySelectorAll('.myclass') or getElementsByClassName('myclass') for multiple elements.

6. What does getElementById return if the id is missing?

null. Check the reference before reading properties like innerText or calling methods.
Olorunfemi Akinlua

Boasting over five years of experience in JavaScript, specializing in technical content writing and UX design. With a keen focus on programming languages, he crafts compelling content and designs …