JavaScript + Node.js track

Lesson 17 · Part 5: DOM

DOM Selection & Querying

`querySelector`, attributes and `textContent`/`innerHTML`

Part 5: DOM2 min readFree lesson

Level: Intermediate | player: 16_async_await

Learning Objectives

  • Understand the concept of DOM tree.
  • Select elements with querySelector, querySelectorAll, and getElementById.
  • Read properties as getAttribute, dataset.
  • Know the difference between textContent and innerHTML (especially XSS).
  • Search for the Parent/Child/Sibling node.

1. What is DOM?

The browser parses HTML and creates a DOM (Document Object Model) tree. JavaScript reads and modifies this tree to change the screen.

2. Select element

const title = document.querySelector("#title");           //first matching
const items = document.querySelectorAll(".item");         // NodeList
const byId = document.getElementById("title");

querySelector accepts CSS selectors as is. querySelectorAll returns a static NodeList, so forEach is possible.

3. Attribute query

const link = document.querySelector("a");
link.getAttribute("href");
link.href;                  //DOM properties
link.dataset.userId;        //data-user-id attribute

4. textContent vs innerHTML

textContent is safe because it is simple text and read/write. innerHTML parses HTML strings, so passing user input as is exposes it to XSS attacks. For external input, always use textContent or sanitize.

5. Tree navigation

el.parentElement;
el.children;
el.firstElementChild;
el.nextElementSibling;

Core example

file Contents covered
index.html HTML page for example
01_query_selector.js Using querySelector/All
02_attributes.js getAttribute / dataset
03_text_html.js textContent vs innerHTML
04_nested.js Parent/Child/Sibling navigation

⚠️ Common Mistakes

  1. Load the script from <head> and access it while the DOM does not exist yet.
  2. Mistake the querySelectorAll result as an array and call .map directly (Array.from required).
  3. Insert user input as is into innerHTML.
  4. Ignoring the subtle differences between getAttribute("class") and el.className.
  5. Depends on behavior when there are multiple elements with the same id.

❓ Frequently Asked Questions (FAQ)

Q1. Which is better, getElementById or querySelector("#id")? A. The performance difference is minimal. For consistency, you can just use querySelector.

Q2. Difference between NodeList and HTMLCollection? A. NodeList is static (or live), HTMLCollection is always live and does not have forEach.

Q3. Key name rules for dataset? A. data-user-id is converted to camel case to dataset.userId.

Example files

The runnable files used in this lesson. Copy them into your own project and experiment.

src/01_query_selector.jsJavaScript
/**
 *querySelector / querySelectorAll / getElementById comparison.
 */
const title = document.querySelector("#title");
console.log("title:", title.textContent);

const items = document.querySelectorAll(".item");
console.log("Number of Items:", items.length);
items.forEach((el) => console.log("-", el.textContent));

const byId = document.getElementById("msg");
console.log("msg:", byId.textContent);
src/02_attributes.jsJavaScript
/**
 *Reading properties and dataset.
 */
const link = document.querySelector("#link");
console.log("href(attr):", link.getAttribute("href"));
console.log("href(prop):", link.href);

document.querySelectorAll(".item").forEach((el) => {
  console.log("id =", el.dataset.id, ", text =", el.textContent);
});
src/03_text_html.jsJavaScript
/**
 *Difference between textContent and innerHTML.
 *There is a risk of XSS if you put user input directly into innerHTML .
 */
const msg = document.querySelector("#msg");
console.log("textContent:", msg.textContent);
console.log("innerHTML:", msg.innerHTML);

msg.textContent = "<b>Safety</b>";
console.log("After textContent:", msg.textContent);
src/04_nested.jsJavaScript
/**
 *Parent/child/sibling node navigation.
 */
const list = document.querySelector("#list");
console.log("Number of children:", list.children.length);
console.log("First child:", list.firstElementChild.textContent);
console.log("Second child:", list.firstElementChild.nextElementSibling.textContent);
console.log("Parent tag:", list.parentElement.tagName);
src/index.htmlHTML
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
<title>DOM selection and query</title>
  </head>
  <body>
<h1 id="title">DOM example</h1>
    <ul id="list">
<li class="item" data-id="1">Apple</li>
<li class="item" data-id="2">Banana</li>
<li class="item" data-id="3">Cherry</li>
    </ul>
<a href="https://example.com" id="link">Example link</a>
    <p id="msg">Hello</p>

    <script src="01_query_selector.js"></script>
    <script src="02_attributes.js"></script>
    <script src="03_text_html.js"></script>
    <script src="04_nested.js"></script>
  </body>
</html>

Assignment

Select all .fruit items in HTML and print the following.

  1. Text of each item
  2. data-color property value

The reference solution is shown below.

Show the reference solution

Try the assignment yourself first — comparing your attempt with a working solution is where most of the learning happens.

homework_01.htmlHTML
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
<title>Assignment 17-1</title>
  </head>
  <body>
    <ul id="fruits">
<li class="fruit" data-color="red">Apple</li>
<li class="fruit" data-color="yellow">Banana</li>
<li class="fruit" data-color="purple">Grapes</li>
    </ul>
    <script src="homework_01.js"></script>
  </body>
</html>
homework_01.jsJavaScript
/**
 *Prints the text and color properties of .fruit elements.
 */
const fruits = document.querySelectorAll(".fruit");
fruits.forEach((el) => {
  console.log(`${el.textContent} -> ${el.dataset.color}`);
});

Learn this lesson with a mentor

Work through the JavaScript + Node.js track on your own, or join a guided cohort at our Pitampura campus and online.

Call NowEnroll Now