Suggest an editImprove this articleRefine the answer for “DOM selectors in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**DOM selectors are the ways to find an element on the page from JavaScript so that you can then change its text, styles or classes, or attach an event handler. The simple methods search by a single criterion: `getElementById` by `id`, `getElementsByClassName` by class, `getElementsByTagName` by tag; they return live collections (HTMLCollection) that update themselves together with the DOM. The modern `querySelector` and `querySelectorAll` accept any CSS selector and return, respectively, the first match or a static NodeList that already has `forEach`.** ```javascript const first = document.querySelector('.menu li.active'); // the first match const all = document.querySelectorAll('.menu li'); // a static NodeList all.forEach((li) => console.log(li.textContent)); ``` **Key point:** `querySelector` / `querySelectorAll` are universal and readable, while `getElementById` and `getElementsBy...` give maximum speed and a live collection.Shown above the full answer for quick recall.Answer (EN)Image**DOM selectors are the ways to find elements on a page with JavaScript.** Without them you cannot interact with HTML at all: you first have to get the element in order to do something with it (change its text or style, remove it, attach an event handler and so on). ## Theory ### TL;DR - A selector is a way to say which element in the DOM you want: by `id`, tag, class, attribute or a full CSS selector. - `getElementById` returns a single element, while `getElementsByClassName` and `getElementsByTagName` return an HTMLCollection. - `querySelector` returns the first match for a CSS selector, `querySelectorAll` returns all matches as a NodeList. - The `getElementsBy...` collections are live: a new element in the DOM shows up in them automatically. The NodeList from `querySelectorAll` is static. - You can narrow the search down: a found element also has `querySelector` and `querySelectorAll`. ### Quick example ```javascript // HTML: <ul class="menu"><li>Home</li><li class="active">Profile</li></ul> const menu = document.querySelector('.menu'); // the first match const items = menu.querySelectorAll('li'); // search inside menu const active = document.querySelector('.menu li.active'); console.log(items.length); // 2 console.log(active.textContent); // Profile ``` ### The main element lookup methods | Method | What it returns | What it takes | Example | | --- | --- | --- | --- | | `getElementById(id)` | a single element | `id` (without `#`) | `document.getElementById("header")` | | `getElementsByClassName(class)` | HTMLCollection (array like) | class name (without `.`) | `document.getElementsByClassName("menu")` | | `getElementsByTagName(tag)` | HTMLCollection | tag name | `document.getElementsByTagName("p")` | | `querySelector(selector)` | the first element | **CSS selector** | `document.querySelector(".menu li")` | | `querySelectorAll(selector)` | NodeList (every match) | **CSS selector** | `document.querySelectorAll("div > p")` | ### Each method in detail **`document.getElementById()`** finds **one element** by its `id` attribute. ```html <h1 id="title">Hello!</h1> ``` ```javascript const el = document.getElementById('title'); console.log(el.textContent); // Hello! ``` Pro: very fast. Cons: works by `id` only and returns a single element. **`document.getElementsByClassName()`** looks for **all elements** with the given class. ```html <p class="text">First</p> <p class="text">Second</p> ``` ```javascript const els = document.getElementsByClassName('text'); console.log(els.length); // 2 ``` Pro: fast and supported everywhere. Con: it returns an **HTMLCollection**, which you have to convert to an array (`Array.from`) before using `forEach`. **`document.getElementsByTagName()`** finds every element by tag. ```javascript const paragraphs = document.getElementsByTagName('p'); ``` It returns a **live collection**: if a new `<p>` appears in the DOM, it is added to the collection automatically. **`document.querySelector()`** uses **CSS selectors** and returns the **first matching** element. ```javascript const item = document.querySelector('.menu li.active'); ``` Pro: universal, it supports everything CSS selectors can express. Con: it returns only one element. **`document.querySelectorAll()`** returns **every element** that matches the CSS selector. ```javascript const items = document.querySelectorAll('.menu li'); items.forEach((li) => console.log(li.textContent)); ``` Pro: it returns a **NodeList**, which already has `forEach()`. Con: the collection does not update itself, unlike `getElementsBy...`. ### Types of selectors (as in CSS) | Selector | Example | Description | | --- | --- | --- | | By tag | `"div"` | every `<div>` | | By class | `".item"` | every element with the class `item` | | By `id` | `"#header"` | the element with `id="header"` | | By attribute | `"[type='text']"` | elements with `type="text"` | | Descendants | `"ul li"` | every `<li>` inside a `<ul>` | | Direct children | `"ul > li"` | only the ones one level deep | | Combined | `"div.item.active"` | `<div class="item active">` | | Pseudo classes | `"li:first-child"`, `"input:checked"` | specific states | ### When to use what | Goal | Better to use | | --- | --- | | Get an element by `id` quickly | `getElementById()` | | Find by class or tag | `getElementsByClassName()` / `getElementsByTagName()` | | A complex lookup (as in CSS) | `querySelector()` / `querySelectorAll()` | | A collection that updates itself | `getElementsBy...` | | A one off static list | `querySelectorAll()` | An example of a combined lookup. HTML: ```html <div class="card"> <h2 class="title">Title</h2> <p class="desc">Description</p> </div> ``` JavaScript: ```javascript const card = document.querySelector('.card'); const title = card.querySelector('.title'); const desc = card.querySelector('.desc'); console.log(title.textContent); // "Title" ``` A practical tip: reach for `querySelector` / `querySelectorAll` by default, they are the universal and modern way and work with any CSS selector. `getElementById` and `getElementsByClassName` are useful where you need maximum performance (legacy code or thousands of elements). ### Working with the elements you found Once the element is found you can do almost anything with it: ```javascript const el = document.querySelector('#myDiv'); el.textContent = 'New text'; // change the content el.style.color = 'red'; // change the style el.classList.add('active'); // add a class el.addEventListener('click', onClick); // attach a handler ``` A short recap of the return values: | Method | Returns | Notes | | --- | --- | --- | | `getElementById(id)` | a single element | fast, unique `id` | | `getElementsByClassName()` | HTMLCollection | a live collection | | `getElementsByTagName()` | HTMLCollection | lookup by tag | | `querySelector()` | the first element | CSS selector | | `querySelectorAll()` | NodeList | every matching element | ### Common mistakes - **Passing `#` or `.` where they are not expected.** `getElementById('#title')` returns `null`: this method takes a bare `id`. `querySelector('#title')`, on the other hand, requires the `#`. - **Calling `forEach` on an HTMLCollection.** `getElementsByClassName` / `getElementsByTagName` have no `forEach`; use `Array.from(els)` first, or switch to `querySelectorAll`. - **Not checking the result for `null`.** `querySelector` and `getElementById` return `null` when nothing is found, and touching `.textContent` then throws immediately. - **Forgetting that collections are live.** A loop over an HTMLCollection that removes elements inside the body skips some of them, because the collection changes as you go. - **Looking for elements before the HTML is parsed.** A script in `<head>` without `defer` runs before the markup exists, so the selector finds nothing. - **Always searching from `document`.** If you already hold a container, call `card.querySelector('.title')`: it is both faster and more precise.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.