🌐 Bài 11: HTML cơ bản & DOM cơ bản

Tìm hiểu HTML và truy cập DOM trong JavaScript

← Quay lại trang chính

1. 🌐 Một Website gồm những thành phần gì?

Trước khi tìm hiểu về DOM, chúng ta cần hiểu rõ một website được xây dựng từ những thành phần nào và chúng hoạt động ra sao.

🏗️ Ba trụ cột chính của một Website:

📄 HTML - Nội dung & Cấu trúc

Vai trò: Xây dựng khung xương và nội dung của trang web

  • Định nghĩa các phần tử: tiêu đề, đoạn văn, hình ảnh, link...
  • Tạo cấu trúc phân cấp (header, main, footer...)
  • Chứa dữ liệu và thông tin hiển thị
Ví dụ: <h1>Tiêu đề</h1>, <p>Đoạn văn</p>

🎨 CSS - Giao diện & Định dạng

Vai trò: Tạo giao diện đẹp và bố cục cho website

  • Màu sắc, font chữ, kích thước
  • Bố cục, vị trí các phần tử
  • Hiệu ứng, animation, responsive
Ví dụ: color: blue;, font-size: 18px;

JavaScript - Tương tác & Logic

Vai trò: Thêm tính tương tác và xử lý logic

  • Xử lý sự kiện (click, input, scroll...)
  • Thay đổi nội dung động
  • Gọi API, xử lý dữ liệu
Ví dụ: button.addEventListener('click', ...)

🏠 Ví dụ: Xây dựng một ngôi nhà

Để hiểu rõ hơn, hãy tưởng tượng website như một ngôi nhà:

  • HTML = Khung xương, tường, cửa, cửa sổ (cấu trúc cơ bản)
  • CSS = Sơn, trang trí, nội thất, ánh sáng (làm đẹp)
  • JavaScript = Hệ thống điện, tự động hóa (tính năng thông minh)

Thiếu HTML → không có nhà. Thiếu CSS → nhà xấu. Thiếu JavaScript → nhà "câm".

🔄 Mối quan hệ giữa HTML - CSS - JavaScript

  1. HTML tạo nội dung → CSS làm đẹp → JavaScript thêm tương tác
  2. HTML không thể thiếu, CSS và JS có thể có hoặc không
  3. JavaScript cần HTML để có phần tử để tương tác
  4. CSS có thể thay đổi bằng JavaScript (dynamic styling)

2. 🌳 DOM là gì trong Website?

Sau khi hiểu website gồm HTML-CSS-JavaScript, giờ chúng ta tìm hiểu DOM - cầu nối quan trọng giữa HTML và JavaScript.

🔍 DOM (Document Object Model) - Định nghĩa

DOMmô hình đối tượng tài liệu - một cách biểu diễn cấu trúc HTML dưới dạng cây đối tượng mà JavaScript có thể hiểu và thao tác.

🎯 Vai trò của DOM:

  • 📖 Đọc: Truy cập nội dung HTML từ JavaScript
  • ✏️ Sửa: Thay đổi nội dung, thuộc tính HTML
  • Thêm: Tạo phần tử HTML mới
  • 🗑️ Xóa: Loại bỏ phần tử HTML
  • 👆 Tương tác: Xử lý sự kiện người dùng

� DOM Tree - Cây cấu trúc

DOM biến HTML thành một cây phân cấp, mỗi thẻ HTML trở thành một node (nút):

📝 HTML Code:

<html>
  <head>
    <title>My Page</title>
  </head>
  <body>
    <h1>Hello</h1>
    <p>World</p>
  </body>
</html>

🌳 DOM Tree:

📄 html
├── 📋 head
│    └── 📝 title
│         └── "My Page"
└── 🎯 body
    ├── 🏷️ h1
    │    └── "Hello"
    └── 📄 p
         └── "World"

🔧 Tại sao cần DOM?

❌ Không có DOM

JavaScript không thể:

  • Đọc nội dung HTML
  • Thay đổi text, hình ảnh
  • Thêm/xóa phần tử
  • Xử lý click, input...
→ Website tĩnh, không tương tác

✅ Có DOM

JavaScript có thể:

  • Tìm phần tử HTML
  • Đọc/sửa nội dung
  • Thay đổi style CSS
  • Tạo website động
→ Website tương tác, sinh động

🎮 Thử ngay: Hiểu DOM qua ví dụ

Click nút bên dưới để xem JavaScript thay đổi HTML thông qua DOM:

🎯 Tiêu đề ban đầu

Đây là đoạn text ban đầu.

📦 Box ban đầu

4. 🏗️ HTML cơ bản & Các thẻ quan trọng

Sau khi hiểu DOM và ID/Class, giờ chúng ta tìm hiểu chi tiết về HTML (HyperText Markup Language) - ngôn ngữ đánh dấu để xây dựng cấu trúc và nội dung trang web.

📋 HTML là gì?

  • HTML = HyperText Markup Language
  • Vai trò: Tạo cấu trúc và nội dung cho website
  • Cách hoạt động: Sử dụng các thẻ (tags) để đánh dấu các phần tử
  • Cú pháp: <tagname>nội dung</tagname>

1. 🏠 Cấu trúc HTML cơ bản

basic-structure.html
<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tiêu đề trang</title>
</head>
<body>
    <!-- Nội dung website ở đây -->
    <h1>Xin chào thế giới!</h1>
    <p>Đây là trang web đầu tiên của tôi.</p>
</body>
</html>

🔍 Giải thích:

  • <!DOCTYPE html> - Khai báo đây là HTML5
  • <html> - Thẻ gốc chứa toàn bộ trang
  • <head> - Thông tin meta (không hiển thị)
  • <body> - Nội dung hiển thị trên trang

2. 📝 Thẻ Tiêu đề (Heading)

headings.html
<h1>Tiêu đề cấp 1 - Quan trọng nhất</h1>
<h2>Tiêu đề cấp 2 - Phần chính</h2>
<h3>Tiêu đề cấp 3 - Tiểu mục</h3>
<h4>Tiêu đề cấp 4</h4>
<h5>Tiêu đề cấp 5</h5>
<h6>Tiêu đề cấp 6 - Nhỏ nhất</h6>

🎯 Kết quả hiển thị:

Tiêu đề cấp 1 - Quan trọng nhất

Tiêu đề cấp 2 - Phần chính

Tiêu đề cấp 3 - Tiểu mục

Tiêu đề cấp 4

Tiêu đề cấp 5
Tiêu đề cấp 6 - Nhỏ nhất

💡 Lưu ý quan trọng:

  • H1 chỉ dùng 1 lần/trang (tiêu đề chính)
  • Không bỏ qua cấp (H1 → H2 → H3...)
  • Quan trọng cho SEO và accessibility

3. 📄 Thẻ Đoạn văn và Text

text-elements.html
<p>Đây là một đoạn văn bình thường.</p>
<p>Đoạn văn có thể chứa <strong>text đậm</strong> và <em>text nghiêng</em>.</p>

<!-- Thẻ ngắt dòng và đường kẻ ngang -->
<p>Dòng này<br>có ngắt dòng ở giữa.</p>
<hr>
<p>Đoạn này sau đường kẻ ngang.</p>

<!-- Thẻ định dạng khác -->
<p>
    <mark>Text được highlight</mark><br>
    <small>Text nhỏ</small><br>
    <del>Text bị gạch xóa</del><br>
    <ins>Text được thêm vào</ins>
</p>

🎯 Kết quả hiển thị:

Đây là một đoạn văn bình thường.

Đoạn văn có thể chứa text đậmtext nghiêng.

Dòng này
có ngắt dòng ở giữa.


Đoạn này sau đường kẻ ngang.

Text được highlight
Text nhỏ
Text bị gạch xóa
Text được thêm vào

4. 📦 Thẻ Container: div và span

containers.html
<!-- DIV: Block element -->
<div style="background: #e3f2fd; padding: 15px; margin: 10px 0; border-radius: 5px;">
    <h4>Khối DIV 1</h4>
    <p>Đây là nội dung trong div. DIV chiếm toàn bộ chiều rộng.</p>
</div>

<div style="background: #e8f5e8; padding: 15px; margin: 10px 0; border-radius: 5px;">
    <h4>Khối DIV 2</h4>
    <p>Div khác sẽ xuống dòng mới.</p>
</div>

<!-- SPAN: Inline element -->
<p>
    Trong câu này có <span style="color: red; background: #ffe6e6;">span màu đỏ</span> 
    và <span style="color: blue; background: #e6f2ff;">span màu xanh</span> 
    trên cùng một dòng.
</p>

🎯 Kết quả hiển thị:

Khối DIV 1

Đây là nội dung trong div. DIV chiếm toàn bộ chiều rộng.

Khối DIV 2

Div khác sẽ xuống dòng mới.

Trong câu này có span màu đỏspan màu xanh trên cùng một dòng.

🔍 Phân biệt div và span:

  • DIV: Block element - chiếm toàn bộ chiều rộng, tự xuống dòng
  • SPAN: Inline element - chỉ chiếm không gian cần thiết, không xuống dòng
  • Sử dụng: div cho layout, span cho định dạng text nhỏ

5. 🔗 Thẻ Liên kết (Anchor)

links.html
<!-- Liên kết đến website khác -->
<a href="https://www.google.com">Đi tới Google</a>

<!-- Mở tab mới -->
<a href="https://www.youtube.com" target="_blank">Mở YouTube tab mới</a>

<!-- Liên kết email -->
<a href="mailto:someone@example.com">Gửi Email</a>

<!-- Liên kết phone -->
<a href="tel:+84123456789">Gọi điện: 0123456789</a>

<!-- Liên kết trong trang (anchor) -->
<a href="#top">Lên đầu trang</a>
<a href="#footer">Xuống cuối trang</a>

<!-- Liên kết tải file -->
<a href="document.pdf" download>Tải PDF</a>

🎯 Kết quả hiển thị:

🌐 Đi tới Google

📺 Mở YouTube tab mới

📧 Gửi Email

📞 Gọi điện: 0123456789

⬆️ Lên đầu trang

📄 Tải PDF

6. 🖼️ Thẻ Hình ảnh (Image)

images.html
<!-- Hình ảnh cơ bản -->
<img src="https://via.placeholder.com/300x200/4facfe/ffffff?text=Demo+Image" 
     alt="Hình ảnh demo">

<!-- Với kích thước tùy chỉnh -->
<img src="https://via.placeholder.com/150x100/28a745/ffffff?text=Small" 
     alt="Hình nhỏ" 
     width="150" 
     height="100">

<!-- Với style CSS -->
<img src="https://via.placeholder.com/200x150/e53e3e/ffffff?text=Rounded" 
     alt="Hình bo góc"
     style="border-radius: 15px; border: 3px solid #ddd;">

<!-- Hình responsive -->
<img src="https://via.placeholder.com/400x250/9c27b0/ffffff?text=Responsive" 
     alt="Hình responsive"
     style="max-width: 100%; height: auto; border-radius: 8px;">

🎯 Kết quả hiển thị:

Hình ảnh demo
Hình nhỏ Hình bo góc
Hình responsive

⚠️ Lưu ý quan trọng:

  • alt bắt buộc - mô tả hình khi không load được
  • src có thể là đường dẫn tương đối hoặc tuyệt đối
  • Nên tối ưu kích thước file để trang load nhanh
  • Sử dụng CSS để làm responsive

7. 📋 Thẻ Danh sách (Lists)

lists.html
<!-- Danh sách không có thứ tự (Unordered List) -->
<ul>
    <li>Mục 1: HTML cơ bản</li>
    <li>Mục 2: CSS styling</li>
    <li>Mục 3: JavaScript
        <ul>
            <li>DOM manipulation</li>
            <li>Event handling</li>
            <li>AJAX requests</li>
        </ul>
    </li>
    <li>Mục 4: Frameworks</li>
</ul>

<!-- Danh sách có thứ tự (Ordered List) -->
<ol>
    <li>Bước 1: Phân tích yêu cầu</li>
    <li>Bước 2: Thiết kế wireframe</li>
    <li>Bước 3: Viết HTML</li>
    <li>Bước 4: Style với CSS</li>
    <li>Bước 5: Thêm JavaScript</li>
    <li>Bước 6: Test và deploy</li>
</ol>

<!-- Danh sách định nghĩa (Description List) -->
<dl>
    <dt>HTML</dt>
    <dd>HyperText Markup Language - ngôn ngữ đánh dấu siêu văn bản</dd>
    
    <dt>CSS</dt>
    <dd>Cascading Style Sheets - bảng định dạng theo tầng</dd>
    
    <dt>JavaScript</dt>
    <dd>Ngôn ngữ lập trình để tạo tính tương tác cho website</dd>
</dl>

🎯 Kết quả hiển thị:

📌 Danh sách không thứ tự:
  • Mục 1: HTML cơ bản
  • Mục 2: CSS styling
  • Mục 3: JavaScript
    • DOM manipulation
    • Event handling
    • AJAX requests
  • Mục 4: Frameworks
🔢 Danh sách có thứ tự:
  1. Bước 1: Phân tích yêu cầu
  2. Bước 2: Thiết kế wireframe
  3. Bước 3: Viết HTML
  4. Bước 4: Style với CSS
  5. Bước 5: Thêm JavaScript
  6. Bước 6: Test và deploy
📖 Danh sách định nghĩa:
HTML
HyperText Markup Language - ngôn ngữ đánh dấu siêu văn bản
CSS
Cascading Style Sheets - bảng định dạng theo tầng
JavaScript
Ngôn ngữ lập trình để tạo tính tương tác cho website

8. 📝 Form Elements - Nhập liệu

form-elements.html
<form>
    <!-- Text inputs -->
    <label for="username">Tên đăng nhập:</label>
    <input type="text" id="username" name="username" placeholder="Nhập tên...">
    
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" placeholder="email@example.com">
    
    <label for="password">Mật khẩu:</label>
    <input type="password" id="password" name="password">
    
    <!-- Number and date -->
    <label for="age">Tuổi:</label>
    <input type="number" id="age" name="age" min="1" max="120">
    
    <label for="birthday">Ngày sinh:</label>
    <input type="date" id="birthday" name="birthday">
    
    <!-- Textarea -->
    <label for="message">Tin nhắn:</label>
    <textarea id="message" name="message" rows="4" placeholder="Nhập tin nhắn..."></textarea>
    
    <!-- Checkboxes -->
    <p>Sở thích:</p>
    <input type="checkbox" id="music" name="hobby" value="music">
    <label for="music">Âm nhạc</label>
    
    <input type="checkbox" id="sports" name="hobby" value="sports">
    <label for="sports">Thể thao</label>
    
    <!-- Radio buttons -->
    <p>Giới tính:</p>
    <input type="radio" id="male" name="gender" value="male">
    <label for="male">Nam</label>
    
    <input type="radio" id="female" name="gender" value="female">
    <label for="female">Nữ</label>
    
    <!-- Select dropdown -->
    <label for="country">Quốc gia:</label>
    <select id="country" name="country">
        <option value="">Chọn quốc gia...</option>
        <option value="vn">Việt Nam</option>
        <option value="us">Hoa Kỳ</option>
        <option value="jp">Nhật Bản</option>
    </select>
    
    <!-- Buttons -->
    <button type="submit">Gửi form</button>
    <button type="reset">Reset</button>
    <button type="button">Button thường</button>
</form>

🎯 Form Demo tương tác:

Sở thích:

Giới tính:

9. 🏗️ HTML5 Semantic Elements

semantic-html5.html
<!DOCTYPE html>
<html>
<head>
    <title>Semantic HTML5</title>
</head>
<body>
    <header>
        <nav>
            <ul>
                <li><a href="#home">Trang chủ</a></li>
                <li><a href="#about">Giới thiệu</a></li>
                <li><a href="#contact">Liên hệ</a></li>
            </ul>
        </nav>
    </header>

    <main>
        <section id="hero">
            <h1>Chào mừng đến website</h1>
            <p>Mô tả ngắn về website...</p>
        </section>

        <section id="content">
            <article>
                <header>
                    <h2>Tiêu đề bài viết</h2>
                    <time datetime="2024-01-15">15 tháng 1, 2024</time>
                </header>
                <p>Nội dung bài viết...</p>
                <footer>
                    <p>Tác giả: John Doe</p>
                </footer>
            </article>
        </section>

        <aside>
            <h3>Sidebar</h3>
            <p>Nội dung phụ, quảng cáo, links liên quan...</p>
        </aside>
    </main>

    <footer>
        <p>&copy; 2024 Website Name. All rights reserved.</p>
    </footer>
</body>
</html>

🎯 Ý nghĩa các thẻ Semantic:

  • <header> - Phần đầu trang/section
  • <nav> - Menu điều hướng
  • <main> - Nội dung chính
  • <section> - Phần/mục của trang
  • <article> - Bài viết độc lập
  • <aside> - Nội dung phụ (sidebar)
  • <footer> - Phần cuối trang/section

🎮 Demo tổng hợp các thẻ HTML

Thử nghiệm với các thẻ HTML đã học:

Click nút phía trên để xem demo các thẻ HTML

🔍 DOM - Truy cập phần tử (GET Methods)

Để làm việc với DOM, điều đầu tiên chúng ta cần biết là cách truy cập các phần tử HTML từ JavaScript.

📍 getElementById() - Truy cập theo ID

Mục đích: Tìm 1 phần tử duy nhất theo thuộc tính id

Sử dụng khi: Cần truy cập phần tử cụ thể, quan trọng (form, title, button chính...)

getElementById.js
// Lấy phần tử theo ID
const title = document.getElementById('demoTitle');
const input = document.getElementById('demoInput');
const button = document.getElementById('demoButton');

// Đọc nội dung
console.log('Tiêu đề:', title.textContent);
console.log('Giá trị input:', input.value);

🔬 Kết quả trả về: HTMLElement Object

getElementById() trả về: Một object HTMLElement duy nhất (hoặc null nếu không tìm thấy)

Ví dụ với <h2 id="demoTitle">:
title.tagName → "H2"
title.id → "demoTitle"
title.textContent → "Nội dung tiêu đề"
title.innerHTML → "Nội dung tiêu đề"
title.className → "" (nếu không có class)
title.style → CSSStyleDeclaration object
title.parentElement → Element cha
title.children → HTMLCollection các element con
Ví dụ với <input id="demoInput">:
input.tagName → "INPUT"
input.type → "text"
input.value → "giá trị người dùng nhập"
input.placeholder → "📝 Nhập dữ liệu..."
input.disabled → false
input.checked → undefined (chỉ có với checkbox/radio)
Ví dụ với <button id="demoButton">:
button.tagName → "BUTTON"
button.type → "button"
button.textContent → "🚀 Nút demo"
button.disabled → false
button.onclick → function hoặc null

🏷️ getElementsByClassName() - Truy cập theo Class

Mục đích: Tìm nhiều phần tử có cùng class name

Sử dụng khi: Thao tác với nhóm phần tử giống nhau (danh sách sản phẩm, card, button...)

getElementsByClassName.js
// Lấy tất cả phần tử có class 'list-item'
const listItems = document.getElementsByClassName('list-item');

// Kết quả là HTMLCollection (giống array)
console.log('Số lượng items:', listItems.length);

// Duyệt qua từng phần tử
for (let i = 0; i < listItems.length; i++) {
    console.log('Item', i + 1, ':', listItems[i].textContent);
}

🔬 Kết quả trả về: HTMLCollection

getElementsByClassName() trả về: HTMLCollection - một danh sách "sống" (live collection)

⚡ Đặc điểm HTMLCollection:
  • Live Collection: Tự động cập nhật khi DOM thay đổi
  • Array-like: Có index [0], [1]... và length
  • Không phải Array: Không có map(), filter(), forEach()
  • Có thể chuyển thành Array: Array.from(collection)
Ví dụ với class="list-item":
listItems.length → 3 (số phần tử)
listItems[0] → HTMLElement đầu tiên
listItems[1] → HTMLElement thứ 2
listItems.item(0) → Tương tự [0]
listItems.namedItem('id') → Tìm theo ID (nếu có)
Truy cập thuộc tính từng element:
listItems[0].tagName → "LI"
listItems[0].textContent → "📋 Mục danh sách 1"
listItems[0].className → "list-item"
listItems[0].parentElement → UL element chứa nó

🎯 querySelector() & querySelectorAll() - CSS Selector

Mục đích: Truy vấn phần tử bằng CSS selector (linh hoạt nhất)

Sử dụng khi: Cần truy vấn phức tạp, kết hợp nhiều điều kiện

querySelector.js
// querySelector: Lấy phần tử đầu tiên
const firstListItem = document.querySelector('.list-item');
const demoBox = document.querySelector('.demo-box');

// querySelectorAll: Lấy tất cả phần tử
const allListItems = document.querySelectorAll('.list-item');
const allButtons = document.querySelectorAll('button');

// CSS selector nâng cao
const firstLi = document.querySelector('ul li:first-child');
const inputText = document.querySelector('input[type="text"]');

console.log('First item:', firstListItem.textContent);
console.log('Tất cả buttons:', allButtons.length);

🔬 Kết quả trả về: Element vs NodeList

📍 querySelector() → Element

Trả về: HTMLElement đầu tiên tìm thấy (hoặc null)

Ví dụ:
element.tagName → "DIV"
element.className → "demo-box"
element.textContent → nội dung
element.style → CSSStyleDeclaration
📋 querySelectorAll() → NodeList

Trả về: NodeList - danh sách "tĩnh" (static)

Ví dụ:
nodeList.length → số phần tử
nodeList[0] → element đầu tiên
nodeList.forEach() → có thể dùng!
nodeList.item(0) → tương tự [0]
⚡ So sánh HTMLCollection vs NodeList:
HTMLCollection (getElementsByClassName):
• Live - tự động cập nhật
• Không có forEach()
• Chỉ chứa Element nodes
NodeList (querySelectorAll):
• Static - không tự động cập nhật
• Có forEach(), entries(), keys()
• Có thể chứa nhiều loại nodes

🔍 Thuộc tính chung của mọi HTML Element

Mọi HTML Element đều có những thuộc tính cơ bản này. Dưới đây là cú pháp và kết quả trả về:

📋 Thuộc tính cơ bản - Thông tin Element

🏷️ tagName - Tên thẻ HTML
Cú pháp: element.tagName
Trả về: String (tên thẻ viết HOA)
Ví dụ:
const div = document.querySelector('div');
console.log(div.tagName); // → "DIV"

const h1 = document.querySelector('h1');
console.log(h1.tagName); // → "H1"
🆔 id - Định danh duy nhất
Cú pháp: element.id (đọc/ghi)
Trả về: String (ID của element)
Ví dụ:
const btn = document.getElementById('myBtn');
console.log(btn.id); // → "myBtn"
btn.id = "newId"; // Thay đổi ID
console.log(btn.id); // → "newId"
🎯 className - Danh sách class (string)
Cú pháp: element.className (đọc/ghi)
Trả về: String (các class cách nhau bằng dấu cách)
Ví dụ:
<div class="btn primary active"></div>
const div = document.querySelector('div');
console.log(div.className); // → "btn primary active"
div.className = "new-class"; // Ghi đè toàn bộ
📝 classList - Danh sách class (DOMTokenList)
Cú pháp: element.classList (chỉ đọc)
Trả về: DOMTokenList (có methods: add, remove, toggle, contains)
Ví dụ:
const div = document.querySelector('div');
div.classList.add('new-class'); // Thêm class
div.classList.remove('old-class'); // Xóa class
div.classList.toggle('active'); // Bật/tắt class
console.log(div.classList.contains('active')); // → true/false

📄 Nội dung Element

📝 innerHTML - HTML bên trong
Cú pháp: element.innerHTML (đọc/ghi)
Trả về: String (HTML code bên trong element)
Ví dụ:
<div><p>Hello <strong>World</strong></p></div>
const div = document.querySelector('div');
console.log(div.innerHTML); // → "<p>Hello <strong>World</strong></p>"
div.innerHTML = "<span>New HTML</span>"; // Thay đổi HTML
📄 textContent - Text thuần túy
Cú pháp: element.textContent (đọc/ghi)
Trả về: String (chỉ text, bỏ qua HTML tags)
Ví dụ:
<div><p>Hello <strong>World</strong></p></div>
const div = document.querySelector('div');
console.log(div.textContent); // → "Hello World"
div.textContent = "New Text"; // Thay đổi text (xóa HTML)
👁️ innerText - Text hiển thị
Cú pháp: element.innerText (đọc/ghi)
Trả về: String (text được render, tôn trọng CSS display/visibility)
Ví dụ:
<div>Text <span style="display:none">Hidden</span></div>
const div = document.querySelector('div');
console.log(div.textContent); // → "Text Hidden"
console.log(div.innerText); // → "Text" (bỏ qua hidden)

🎨 Style & Layout - Kích thước và Vị trí

🎨 style - Inline CSS styles
Cú pháp: element.style.propertyName (đọc/ghi)
Trả về: CSSStyleDeclaration object
Ví dụ:
const div = document.querySelector('div');
div.style.backgroundColor = 'red'; // Đặt màu nền
div.style.width = '200px'; // Đặt chiều rộng
console.log(div.style.color); // → "" (nếu không set inline)
📐 clientWidth/Height - Kích thước nội dung
Cú pháp: element.clientWidth, element.clientHeight
Trả về: Number (pixel, không bao gồm border/scrollbar)
Ví dụ:
const div = document.querySelector('div');
console.log(div.clientWidth); // → 200 (chiều rộng content + padding)
console.log(div.clientHeight); // → 100 (chiều cao content + padding)
📏 offsetWidth/Height - Tổng kích thước
Cú pháp: element.offsetWidth, element.offsetHeight
Trả về: Number (pixel, bao gồm border + scrollbar)
Ví dụ:
const div = document.querySelector('div');
console.log(div.offsetWidth); // → 210 (width + padding + border)
console.log(div.offsetHeight); // → 110 (height + padding + border)
📍 offsetTop/Left - Vị trí từ parent
Cú pháp: element.offsetTop, element.offsetLeft
Trả về: Number (pixel từ offsetParent)
Ví dụ:
const div = document.querySelector('div');
console.log(div.offsetTop); // → 50 (khoảng cách từ trên)
console.log(div.offsetLeft); // → 20 (khoảng cách từ trái)

🌳 DOM Navigation - Di chuyển trong cây DOM

👆 parentElement - Element cha
Cú pháp: element.parentElement
Trả về: Element (element cha) hoặc null
Ví dụ:
<div><p id="child">Text</p></div>
const p = document.getElementById('child');
console.log(p.parentElement); // → DIV element
console.log(p.parentElement.tagName); // → "DIV"
👶 children - Elements con
Cú pháp: element.children
Trả về: HTMLCollection (danh sách elements con)
Ví dụ:
<ul><li>Item 1</li><li>Item 2</li></ul>
const ul = document.querySelector('ul');
console.log(ul.children.length); // → 2
console.log(ul.children[0].textContent); // → "Item 1"
🥇 firstElementChild / lastElementChild
Cú pháp: element.firstElementChild, element.lastElementChild
Trả về: Element (con đầu/cuối) hoặc null
Ví dụ:
<ul><li>First</li><li>Middle</li><li>Last</li></ul>
const ul = document.querySelector('ul');
console.log(ul.firstElementChild.textContent); // → "First"
console.log(ul.lastElementChild.textContent); // → "Last"
👫 nextElementSibling / previousElementSibling
Cú pháp: element.nextElementSibling, element.previousElementSibling
Trả về: Element (anh em kế tiếp/trước) hoặc null
Ví dụ:
<div><p>Para 1</p><p id="middle">Para 2</p><p>Para 3</p></div>
const middle = document.getElementById('middle');
console.log(middle.previousElementSibling.textContent); // → "Para 1"
console.log(middle.nextElementSibling.textContent); // → "Para 3"

🎯 Thuộc tính đặc biệt theo từng loại Element

📝 Input Elements:

input.value - Giá trị nhập
input.type - Loại input
input.placeholder - Text gợi ý
input.checked - Trạng thái check
input.disabled - Có bị vô hiệu hóa
input.required - Có bắt buộc
input.maxLength - Độ dài tối đa

🔗 Link Elements (a):

link.href - Đường dẫn URL
link.target - Cách mở (_blank...)
link.download - Tên file tải
link.rel - Quan hệ (nofollow...)
link.hostname - Tên domain
link.pathname - Đường dẫn
link.search - Query parameters

🖼️ Image Elements (img):

img.src - Đường dẫn ảnh
img.alt - Text thay thế
img.width - Chiều rộng
img.height - Chiều cao
img.naturalWidth - Chiều rộng gốc
img.naturalHeight - Chiều cao gốc
img.complete - Đã load xong?

📋 Form Elements:

form.action - URL gửi form
form.method - GET hoặc POST
form.elements - Tất cả controls
select.selectedIndex - Option được chọn
select.options - Danh sách options
textarea.rows - Số dòng
textarea.cols - Số cột

🎮 Thực hành: Truy cập phần tử DOM

Thử các phương thức truy cập DOM với HTML demo phía trên ⬆️

3. 🏷️ ID và Class trong HTML - Cách đặt tên cho phần tử

Trước khi học cách truy cập DOM, chúng ta cần hiểu ID và Class - hai cách quan trọng để "đặt tên""phân loại" các phần tử HTML.

🆔 ID (Identifier) - Định danh duy nhất

📝 Định nghĩa & Đặc điểm:

  • Duy nhất: Mỗi ID chỉ được dùng 1 lần trong trang
  • Ưu tiên cao: CSS và JS ưu tiên ID hơn class
  • Mục đích: Định danh phần tử quan trọng, duy nhất
  • Tốc độ: Truy cập nhanh nhất từ JavaScript

💡 Sử dụng khi nào:

  • Header chính, footer trang
  • Navigation menu chính
  • Form đăng nhập, đăng ký
  • Button quan trọng (submit, login...)
  • Phần tử cần truy cập từ JavaScript

🔧 Cú pháp và Ví dụ:

id-examples.html
<!-- ✅ Đúng: Mỗi ID chỉ dùng 1 lần -->
<header id="mainHeader">Header chính</header>
<nav id="primaryNav">Menu điều hướng</nav>
<form id="loginForm">Form đăng nhập</form>
<button id="submitBtn">Gửi</button>
<footer id="siteFooter">Footer</footer>

<!-- ❌ Sai: Không được trùng ID -->
<div id="content">Nội dung 1</div>
<div id="content">Nội dung 2</div>  <!-- Sai! -->

🎯 Class - Phân loại nhóm phần tử

📝 Định nghĩa & Đặc điểm:

  • Tái sử dụng: Nhiều phần tử có thể cùng class
  • Nhóm hóa: Phân loại phần tử cùng kiểu
  • Linh hoạt: 1 phần tử có thể có nhiều class
  • CSS: Dễ dàng style nhiều phần tử cùng lúc

💡 Sử dụng khi nào:

  • Buttons cùng style
  • Cards sản phẩm
  • List items
  • Các phần tử cần style giống nhau
  • Component có thể tái sử dụng

🔧 Cú pháp và Ví dụ:

class-examples.html
<!-- ✅ Đúng: Nhiều phần tử cùng class -->
<button class="btn">Lưu</button>
<button class="btn">Hủy</button>
<button class="btn">Xóa</button>

<!-- ✅ Đúng: Một phần tử nhiều class -->
<button class="btn btn-primary">Button chính</button>
<button class="btn btn-secondary">Button phụ</button>

<!-- ✅ Đúng: Danh sách cùng class -->
<div class="product-card">Sản phẩm 1</div>
<div class="product-card">Sản phẩm 2</div>
<div class="product-card">Sản phẩm 3</div>

⚖️ So sánh ID vs Class

Tiêu chí 🆔 ID 🎯 Class
Số lượng 1 ID / trang Không giới hạn
Tái sử dụng ❌ Không ✅ Có
CSS Selector #idName .className
JS Method getElementById() getElementsByClassName()
Ưu tiên CSS Cao Thấp hơn
Tốc độ truy cập Nhanh nhất Nhanh

📋 Quy tắc đặt tên ID và Class

✅ Nên làm:

  • Dùng tiếng Anh
  • Có ý nghĩa rõ ràng
  • Dùng dấu gạch ngang (-) hoặc camelCase
  • Bắt đầu bằng chữ cái
  • ID cho phần tử quan trọng
  • Class cho nhóm phần tử
Ví dụ tốt:
id="userProfile"
class="btn-primary"
class="product-card"

❌ Không nên:

  • Dùng tiếng Việt có dấu
  • Tên không có ý nghĩa
  • Bắt đầu bằng số
  • Có khoảng trắng
  • Ký tự đặc biệt (@, !, %...)
  • Trùng ID trong cùng trang
Ví dụ tệ:
id="1button" ❌
class="nút màu xanh" ❌
id="my button" ❌

🎮 Thử ngay: Phân biệt ID và Class

Quan sát HTML demo bên dưới để hiểu cách sử dụng ID và Class:

<h3 id="pageTitle">Tiêu đề chính</h3>
<button class="btn">Lưu</button>
<button class="btn">Hủy</button>
<button class="btn btn-danger">Xóa</button>
<div id="userInfo" class="card">Thông tin user</div>
<div class="card">Card khác</div>

🎯 Tiêu đề chính (ID: pageTitle)

📋 Thông tin user (ID: userInfo, Class: card)
📋 Card khác (Class: card)

📝 Bài tập thực hành

  1. Bài 1: Truy cập và đọc thông tin
    Yêu cầu: Sử dụng các phương thức DOM để:
    - Lấy nội dung của tiêu đề trang
    - Đếm số lượng button trên trang
    - Lấy giá trị của input đầu tiên
    - Hiển thị thông tin ra console
  2. Bài 2: So sánh các phương thức
    Yêu cầu: Tạo HTML có nhiều div với class 'item':
    - Dùng getElementsByClassName để lấy tất cả
    - Dùng querySelectorAll để lấy tất cả
    - So sánh kết quả và hiệu suất
  3. Bài 3: CSS Selector nâng cao
    Yêu cầu: Sử dụng querySelector với selector phức tạp:
    - Lấy li cuối cùng trong ul
    - Lấy input có placeholder chứa "email"
    - Lấy div con đầu tiên của container
💡 Lưu ý: Đây là nền tảng để học Bài 12: DOM Nâng cao - nơi chúng ta sẽ học cách thay đổi, thêm, xóa phần tử và xử lý sự kiện!