15: DOM Manipulation
เชื่อมต่อ JavaScript เข้ากับ HTML ด้วย DOM
DOM คืออะไร?
DOM (Document Object Model) คือโครงสร้างของหน้าเว็บที่แปลง HTML ให้เป็น Object เพื่อให้ JavaScript เข้าไป หยิบ (Select), แก้ไข (Manipulate), และ สั่งงาน ได้
1. การหยิบ Element (Selectors)
ก่อนจะเปลี่ยน หรือสั่งงานอะไร จะต้องเลือก Element ที่ต้องการ จาก HTML Elements หลาย ๆ อันในหน้าเว็บให้ถูกต้องก่อน
<!-- 1. หัวข้อหลัก (มี ID) -->
<h1 id="title">Welcome</h1>
<!-- 2. รายการผลไม้ (มี Class เหมือนกันหลายตัว) -->
<ul>
<li class="fruit">Apple</li>
<li class="fruit">Banana</li>
<li class="fruit">Orange</li>
</ul>
1.1 document.querySelector()
หยิบ "ตัวแรกที่เจอ" (ได้ของชิ้นเดียว)
💻 JS Code:
// หยิบด้วย ID (#)
let h1 = document.querySelector("#title");
console.log(h1);
📄 Result (สิ่งที่ได้):
1.2 document.querySelectorAll()
หยิบ "ทุกตัวที่เจอ" (ได้เป็น List)
💻 JS Code:
// หยิบด้วย Class (.)
let list = document.querySelectorAll(".fruit");
console.log(list);
📄 Result (สิ่งที่ได้):
<li class="fruit">Apple</li>,
<li class="fruit">Banana</li>,
<li class="fruit">Orange</li>
]
2. การแก้ไข (Manipulation)
พอหยิบมาได้แล้ว ก็จะสามารถสั่งให้ Element ที่หยิบมาเปลี่ยนแปลงได้
| คำสั่ง | หน้าที่ | ตัวอย่าง |
|---|---|---|
element.innerText |
เปลี่ยนข้อความข้างใน | title.innerText = "สวัสดีชาวโลก"; |
element.innerHTML |
เปลี่ยนไส้ใน (ใส่ HTML Tag ได้) ⚠️ ล้างของเก่าทิ้งหมด |
box.innerHTML = "<b>ตัวหนา</b>";
|
element.insertAdjacentHTML
|
แทรก HTML โดย ไม่ลบของเก่า เลือกตำแหน่ง (position) ได้ 4 จุด:
|
list.insertAdjacentHTML("beforeend", "<li>New</li>");
|
element.classList |
จัดการ Class CSS |
box.classList.add("active");box.classList.remove("hide");box.classList.toggle("dark");
|
element.setAttribute() |
เปลี่ยน Attribute (เช่น src, href) | img.setAttribute("src", "cat.jpg"); |
element.style |
เปลี่ยน CSS โดยตรง (ใช้ CamelCase) | box.style.backgroundColor = "red"; |
เพิ่มเติม: สั่งงานด้วยการ Click
ปกติ JS จะรันทันทีที่เปิดเว็บ แต่ถ้าอยากให้ "กดปุ่มก่อนค่อยรัน" ต้องใช้ onclick ใน HTML
<!-- เมื่อกดปุ่ม -> เรียกฟังก์ชัน changeColor() -->
<button onclick="changeColor()">กดฉันสิ</button>
function changeColor() {
// โค้ดในนี้จะทำงานเมื่อปุ่มถูกกดเท่านั้น!
alert("ปุ่มถูกกดแล้วจ้า!");
}
3. ตัวอย่างการนำไปใช้จริง: Dark Mode Toggle
มาดูเทคนิคยอดฮิตอย่างการทำ "Dark Mode" กัน ว่าเบื้องหลังมันทำงานอย่างไร (ใช้ความรู้เรื่อง classList ที่เรียนไป)
Example: Dark Mode Card
ลองกดปุ่มด้านขวา เพื่อดูการเปลี่ยนแปลงของ Class
หลักการทำงาน:
- HTML: มีปุ่มที่ผูก
onclick="toggleDarkMode()"เอาไว้ - CSS: เราเตรียม Class ชื่อ
.dark-mode-themeไว้ (เปลี่ยนสีพื้นหลัง/ตัวอักษร) - JS: ใช้คำสั่ง
classList.toggle()เพื่อสลับ Class นั้นใส่ในการ์ด (มีก็เอาออก/ไม่มีก็ใส่เพิ่ม)
function toggleDarkMode() {
// 1. เลือก Element เป้าหมาย (ตัวการ์ด)
let card = document.querySelector("#exampleCard");
// 2. สลับ Class (Toggle)
// ถ้ามี class 'dark-mode-theme' -> เอาออก
// ถ้าไม่มี -> ใส่เพิ่ม
card.classList.toggle("dark-mode-theme");
}
Workshop: สร้างกล่องข้อความมหัศจรรย์ (Magic Box)
โจทย์:
ให้สร้างกล่องข้อความ 1 กล่อง และปุ่ม 1 ปุ่ม เมื่อกดปุ่ม ให้กล่องข้อความ เปลี่ยนรูปร่างหน้าตา (เช่น เปลี่ยนสีพื้นหลัง หรือขยายขนาด) โดยใช้การสลับ Class
1. สร้าง HTML
- สร้าง
<div>กำหนด id="box" และใส่ข้อความข้างใน - สร้าง
<button>ใส่ข้อความ "แปลงร่าง" และกำหนด onclick
2. กำหนด CSS
- ตกแต่ง
#boxตามใจชอบ (เช่น ใส่ขอบ, สีพื้น) - สร้าง Class พิเศษชื่อ
.active(กำหนดสีพื้นหลังใหม่ หรือ font size ใหญ่ขึ้น)
3. เขียน JS สั่งงาน
- สร้างฟังก์ชัน
- เขียนโค้ด JavaScript เพื่อเลือกกล่อง
divที่สร้างขึ้น - สั่งให้ฟังก์ชันสลับ Class การแสดงผลของกล่อง
Practice Mission: ร้านค้าออนไลน์
สถานการณ์:
คุณได้รับข้อมูลสินค้า (Array of Objects) จาก Backend หน้าที่ของคุณคือ สร้าง HTML ของสินค้าแต่ละชิ้น ขึ้นมาแสดงบนหน้าเว็บ และทำให้ปุ่ม 'กรองสินค้า' ใช้งานได้จริง
Requirements:
- Data: สร้างตัวแปร
productsเก็บข้อมูลสินค้า - Render Function: สร้างฟังก์ชันที่รับค่า
category- ใช้
.filter()เพื่อเลือกสินค้าตามหมวดหมู่ (ถ้าเป็น 'all' ให้เอาทั้งหมด) - ใช้
.map()เปลี่ยนข้อมูลเป็น HTML String (Template Literal) - เพิ่มโค้ด HTML ของสินค้าแต่ละชิ้นใส่
div#productContainer
- ใช้
- Style: ถ้าสินค้าไหน
inStock: falseให้เปลี่ยนสีชื่อสินค้าเป็นสีแดง มีเส้นขีดกลางtext-decoration-line-through(สามารถใช้ Ternary Operator ใน HTML String ได้)
const productsMock = [
{ name: "Apple", cat: "Fruit", price: 30, inStock: true },
{ name: "Banana", cat: "Fruit", price: 20, inStock: false },
{ name: "Mouse", cat: "Tech", price: 500, inStock: true },
{ name: "Keyboard", cat: "Tech", price: 1200, inStock: true },
{ name: "Orange", cat: "Fruit", price: 40, inStock: true }
];
<div class="p-2 bg-white border rounded d-flex justify-content-between">
<div><span class="text-primary">Apple</span></div>
<span class="badge bg-secondary">30.-</span>
</div>