Here are concrete code examples showing how selectors and combinators target specific nodes in the DOM tree using JavaScript.
Imagine this HTML structure as our blueprint/instance:
<div id="app" class="container">
<h1 id="main-header">Welcome to the App</h1>
<div class="card" data-active="true">
<p class="intro">This is a direct child paragraph.</p>
<div class="nested-wrapper">
<p>This is a deeply nested paragraph.</p>
</div>
</div>
<p class="sibling-text">First paragraph after the card.</p>
<p class="sibling-text">Second paragraph after the card.</p>
</div>
1. Examples of Selectors
Selectors target elements based on their type, class, ID, or attributes.
- ID Selector (
#): Targets a unique element by itsidattribute.
// Selects the <h1> element
const header = document.querySelector('#main-header');
header.style.color = 'navy';
- Class Selector (
.): Targets all elements sharing a specificclassattribute.
// Selects all elements with the class 'card'
const cards = document.querySelectorAll('.card');
- Type Selector (Tag name): Targets all elements of a specific HTML tag.
// Selects every <p> tag in the entire DOM tree
const allParagraphs = document.querySelectorAll('p');
- Attribute Selector (
[...]): Targets elements based on an attribute and its value.
// Selects elements where data-active equals "true"
const activeCard = document.querySelector('[data-active="true"]');
2. Examples of Combinators
Combinators define the relationship between selectors to navigate the DOM tree hierarchy.
- Descendant Combinator (Space
): Finds matching elements anywhere inside an ancestor, no matter how deep.
// Matches BOTH paragraphs (<p class="intro"> and the nested one)
// because they are both inside .card
const paragraphsInCard = document.querySelectorAll('.card p');
- Child Combinator (
>): Finds matching elements that are direct children (one level deep).
// Matches ONLY <p class="intro">.
// It IGNORES the deeply nested paragraph because it's wrapped inside .nested-wrapper.
const directParagraphs = document.querySelectorAll('.card > p');
- Adjacent Sibling Combinator (
+): Finds an element that immediately follows another specific element.
// Matches ONLY the FIRST <p class="sibling-text">
// because it sits directly below the .card element.
const immediateNext = document.querySelector('.card + p');
- General Sibling Combinator (
~): Finds all sibling elements that appear after a given element.
// Matches BOTH <p class="sibling-text"> elements
// because they share the same parent and come after .card.
const allFollowingSiblings = document.querySelectorAll('.card ~ p');