querySelector
querySelector returns the first element matching a CSS selector.
Basic Usage
// By ID
const header = document.querySelector('#header');
// By class
const active = document.querySelector('.active');
// By tag
const firstDiv = document.querySelector('div');
// Complex selectors
const navLink = document.querySelector('nav a.active');
const formInput = document.querySelector('form input[type="email"]');
Return Value
// Returns Element or null
const element = document.querySelector('.nonexistent');
console.log(element); // null
// Always check before using
const el = document.querySelector('.might-not-exist');
if (el) {
el.classList.add('found');
}
Performance Tips
// BAD: Multiple queries for same element
const container = document.querySelector('.container');
const title = document.querySelector('.container .title');
const text = document.querySelector('.container .text');
// GOOD: Query from container
const container = document.querySelector('.container');
const title = container.querySelector('.title');
const text = container.querySelector('.text');
// GOOD: Use specific selectors
const specific = document.querySelector('#myForm .email-input');
Complex Selectors
// Attribute selectors
const required = document.querySelector('input[required]');
const link = document.querySelector('a[href^="https"]');
const csv = document.querySelector('a[href$=".csv"]');
// Pseudo-selectors
const firstItem = document.querySelector('li:first-child');
const lastItem = document.querySelector('li:last-child');
const disabled = document.querySelector('input:disabled');
// Adjacent sibling
const nextParagraph = document.querySelector('p + p');
// Child combinator
const directChild = document.querySelector('ul > li');
getElementById
getElementById is the fastest way to select a single element by its ID attribute.
Basic Usage
const header = document.getElementById('header');
const mainContent = document.getElementById('main-content');
Performance Comparison
// Fastest: getElementById (direct lookup)
const byId = document.getElementById('myId');
// Fast: querySelector with #
const byQuery = document.querySelector('#myId');
// Slower: querySelector with other selectors
const byClass = document.querySelector('.myClass');
// Slowest: getElementsByTagName/getElementsByClassName
const allDivs = document.getElementsByTagName('div');
When to Use Each
// Use getElementById when:
// 1. You know the exact ID
// 2. Maximum performance needed
const criticalElement = document.getElementById('critical');
// Use querySelector when:
// 1. Need complex selectors
// 2. Selecting by non-ID attribute
const complex = document.querySelector('nav ul li.active a');
// Use getElementsByClassName when:
// 1. Need live HTMLCollection
// 2. Working with multiple elements of same class
const allItems = document.getElementsByClassName('item');
// allItems updates automatically when DOM changes
ID Uniqueness
// IDs should be unique in the page
<div id="myId">First</div>
<div id="myId">Second</div> // Invalid HTML!
// getElementById returns first match
const el = document.getElementById('myId'); // First div only
Getting ID from Element
const element = document.querySelector('.someClass');
console.log(element.id); // 'myId' (property)
console.log(element.getAttribute('id')); // 'myId' (method)
querySelectorAll
querySelectorAll returns a static NodeList of all matching elements.
Basic Usage
// Returns NodeList
const items = document.querySelectorAll('.item');
console.log(items.length); // Number of matches
// Iterate with forEach
items.forEach(item => {
console.log(item.textContent);
});
// Convert to array for more methods
const itemsArray = Array.from(items);
const filtered = itemsArray.filter(item => item.classList.contains('active'));
Static vs Live
// querySelectorAll returns STATIC NodeList
const staticList = document.querySelectorAll('.item');
console.log(staticList.length); // 3
// Add new element
const newItem = document.createElement('li');
newItem.className = 'item';
document.querySelector('ul').appendChild(newItem);
console.log(staticList.length); // Still 3 (static!)
// getElementsByClassName returns LIVE HTMLCollection
const liveList = document.getElementsByClassName('item');
console.log(liveList.length); // 3
// After adding new item:
console.log(liveList.length); // 4 (live!)
NodeList Methods
const items = document.querySelectorAll('.item');
// forEach
items.forEach((item, index) => {
console.log(`Item ${index}:`, item);
});
// entries, keys, values
for (const [index, item] of items.entries()) {
console.log(index, item);
}
// Array.from for array methods
const arr = Array.from(items);
arr.map(...).filter(...).reduce(...);
// Spread syntax
const arr2 = [...items];
Performance Tips
// BAD: Multiple queries
const items = document.querySelectorAll('.container .item');
const activeItems = document.querySelectorAll('.container .item.active');
// GOOD: Query once, filter
const allItems = document.querySelectorAll('.container .item');
const activeItems = [...allItems].filter(item =>
item.classList.contains('active')
);
// GOOD: Use specific selectors
const specific = document.querySelectorAll('ul.list > li.item');
Practice Problems
Create a reusable React component implementing Selecting Elements. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for Selecting Elements using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize Selecting Elements for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. What does querySelector return?
2. What is the fastest way to select an element by ID?
3. What is the difference between querySelectorAll and getElementsByClassName?
4. How do you convert a NodeList to an array?
Flashcards
Question
What does querySelector return?
Click to reveal answer
Answer
The first element matching a CSS selector, or null if no match.
Question
When to use getElementById vs querySelector?
Click to reveal answer
Answer
getElementById for known IDs (fastest). querySelector for complex selectors or non-ID attributes.
Question
What is a static NodeList?
Click to reveal answer
Answer
A snapshot that doesn't update when the DOM changes. Returned by querySelectorAll.
Question
How to iterate a NodeList?
Click to reveal answer
Answer
Use forEach(), or convert to array with Array.from() or spread [...] for map/filter/reduce.
Question
What is Selecting Elements?
Click to reveal answer
Answer
Selecting Elements is a key concept in frontend development.
Revision Notes
Key Takeaways
- 1.querySelector returns first match or null
- 2.getElementById is fastest for ID selection
- 3.querySelectorAll returns static NodeList
- 4.Convert NodeList to array for array methods
- 5.Use specific selectors for better performance
Interview Tips
- •Explain when to use each selection method
- •Show the difference between static and live collections
- •Demonstrate complex CSS selectors for selection
- •Discuss performance implications of selection methods
Cheat Sheet
Selecting Elements Cheat Sheet
Single Elements
document.getElementById('id') // Fastest
document.querySelector('.class') // First match
document.querySelector('#id') // By ID
Multiple Elements
document.querySelectorAll('.class') // Static NodeList
document.getElementsByClassName('c') // Live HTMLCollection
document.getElementsByTagName('div') // Live HTMLCollection
Static vs Live
- querySelectorAll: Static (snapshot)
- getElementsBy*: Live (auto-updates)
Converting to Array
const arr = Array.from(nodeList);
const arr = [...nodeList];