HTML Templates และ Reusable Components
ในบทนี้ เราจะมาเรียนรู้เกี่ยวกับการสร้าง HTML Templates และ Reusable Components ซึ่งเป็นเทคนิคสำคัญในการพัฒนาเว็บไซต์ขนาดใหญ่ ที่จะช่วยให้โค้ดของเราเป็นระเบียบ อ่านง่าย และสามารถนำกลับมาใช้ใหม่ได้หลายครั้ง ลดความซ้ำซ้อนและเพิ่มประสิทธิภาพในการพัฒนาอย่างมาก
การสร้าง HTML Templates ด้วย <template> tag
HTML5 ได้เพิ่มแท็ก <template> เข้ามา ซึ่งเป็นแท็กที่ใช้สำหรับเก็บ HTML markup ที่เราต้องการนำไปใช้ซ้ำๆ โดยเบราว์เซอร์จะไม่แสดงเนื้อหาภายในแท็ก <template> จนกว่าเราจะสั่งให้มันแสดงผลผ่าน JavaScript
ตัวอย่างการใช้งาน <template>
<template id="product-template">
<div class="product">
<h3 class="product-name"></h3>
<p class="product-description"></p>
<p class="product-price"></p>
<button class="add-to-cart">Add to Cart</button>
</div>
</template>
จากตัวอย่างข้างต้น เราได้สร้าง template ที่มี id เป็น "product-template" ภายใน template นี้มีโครงสร้าง HTML สำหรับแสดงข้อมูลสินค้า ซึ่งประกอบไปด้วยชื่อสินค้า คำอธิบาย ราคาสินค้า และปุ่ม Add to Cart
การใช้ JavaScript เพื่อ clone และ inject templates
เมื่อเรามี template แล้ว ขั้นตอนต่อไปคือการใช้ JavaScript เพื่อนำ template นั้นมา clone และ inject เข้าไปใน DOM (Document Object Model) เพื่อแสดงผลบนหน้าเว็บ
ขั้นตอนการใช้งาน JavaScript กับ <template>
- เข้าถึง Template: ใช้
document.getElementById()หรือdocument.querySelector()เพื่อเข้าถึง template element - Clone Template: ใช้
template.content.cloneNode(true)เพื่อสร้างสำเนา (clone) ของเนื้อหาภายใน template - แก้ไขข้อมูล: แก้ไขข้อมูลใน clone node ให้เป็นข้อมูลที่เราต้องการแสดง
- Inject เข้า DOM: ใช้
appendChild()หรือinsertBefore()เพื่อเพิ่ม clone node เข้าไปใน DOM
ตัวอย่างโค้ด JavaScript
// ข้อมูลสินค้า
const products = [
{ name: "Product 1", description: "This is product 1", price: 19.99 },
{ name: "Product 2", description: "This is product 2", price: 29.99 },
{ name: "Product 3", description: "This is product 3", price: 39.99 },
];
// เข้าถึง template
const template = document.getElementById("product-template");
// เข้าถึง container ที่เราจะใส่สินค้า
const productContainer = document.getElementById("product-container");
// Loop ผ่านข้อมูลสินค้าแต่ละตัว
products.forEach(product => {
// Clone template
const productElement = template.content.cloneNode(true);
// แก้ไขข้อมูลใน clone node
productElement.querySelector(".product-name").textContent = product.name;
productElement.querySelector(".product-description").textContent = product.description;
productElement.querySelector(".product-price").textContent = `$${product.price}`;
// Inject เข้า DOM
productContainer.appendChild(productElement);
});
HTML ที่จำเป็นสำหรับการรันตัวอย่าง
<div id="product-container">
<!-- สินค้าจะถูกเพิ่มเข้ามาที่นี่ -->
</div>
<template id="product-template">
<div class="product">
<h3 class="product-name"></h3>
<p class="product-description"></p>
<p class="product-price"></p>
<button class="add-to-cart">Add to Cart</button>
</div>
</template>
จากตัวอย่างโค้ด เราได้ทำการ loop ผ่านข้อมูลสินค้าแต่ละตัว สร้าง clone node จาก template และแก้ไขข้อมูลใน clone node ให้ตรงกับข้อมูลสินค้านั้นๆ จากนั้นก็ทำการ inject clone node เข้าไปใน container ที่เราเตรียมไว้
การสร้าง Reusable HTML Components ด้วย Custom Elements (เบื้องต้น)
Custom Elements เป็น Web Component API ที่ช่วยให้เราสามารถสร้าง HTML elements ของตัวเองได้ ซึ่ง elements เหล่านี้สามารถนำกลับมาใช้ใหม่ได้ และมีพฤติกรรมที่กำหนดเองได้ ทำให้เราสามารถสร้าง components ที่ซับซ้อนและ reusable ได้อย่างง่ายดาย
ขั้นตอนการสร้าง Custom Element
- สร้าง Class: สร้าง JavaScript class ที่ extends
HTMLElement - กำหนด Lifecycle Callbacks: กำหนด lifecycle callbacks เช่น
connectedCallback,disconnectedCallback,attributeChangedCallbackเพื่อจัดการกับพฤติกรรมของ element - Define Element: ใช้
customElements.define()เพื่อ register element กับเบราว์เซอร์
ตัวอย่างการสร้าง Custom Element
// สร้าง class ที่ extends HTMLElement
class ProductCard extends HTMLElement {
constructor() {
super();
// สร้าง shadow DOM
this.attachShadow({ mode: 'open' });
// สร้าง template
this.shadowRoot.innerHTML = `
<style>
.product {
border: 1px solid #ccc;
padding: 10px;
margin-bottom: 10px;
}
.product-name {
font-size: 1.2em;
font-weight: bold;
}
</style>
<div class="product">
<h3 class="product-name"></h3>
<p class="product-description"></p>
<p class="product-price"></p>
<button class="add-to-cart">Add to Cart</button>
</div>
`;
}
// Lifecycle callback ที่ทำงานเมื่อ element ถูกเพิ่มเข้า DOM
connectedCallback() {
this.shadowRoot.querySelector(".product-name").textContent = this.getAttribute("name");
this.shadowRoot.querySelector(".product-description").textContent = this.getAttribute("description");
this.shadowRoot.querySelector(".product-price").textContent = `$${this.getAttribute("price")}`;
}
}
// Define element
customElements.define('product-card', ProductCard);
การใช้งาน Custom Element ใน HTML
<product-card
name="Product 4"
description="This is product 4"
price="49.99">
</product-card>
จากตัวอย่างโค้ด เราได้สร้าง custom element ชื่อ product-card ซึ่งรับ attributes เป็น name, description และ price เมื่อเราใช้งาน product-card ใน HTML เบราว์เซอร์จะสร้าง instance ของ class ProductCard และแสดงผลตามที่เรากำหนดไว้ใน shadow DOM
Shadow DOM: เป็นส่วนสำคัญของ Web Components ที่ช่วยให้เราสามารถ encapsulate styles และ markup ของ component ได้ ทำให้ styles ของ component ไม่กระทบกับ styles อื่นๆ ในหน้าเว็บ และทำให้ component มีความ reusable มากยิ่งขึ้น
ประโยชน์ของการใช้ Templates และ Components
- Code Reusability: สามารถนำโค้ดกลับมาใช้ใหม่ได้หลายครั้ง ลดความซ้ำซ้อน
- Maintainability: โค้ดเป็นระเบียบ อ่านง่าย และแก้ไขได้ง่าย
- Performance: ลดขนาดไฟล์ HTML และเพิ่มประสิทธิภาพในการ render หน้าเว็บ
- Scalability: เหมาะสำหรับพัฒนาเว็บไซต์ขนาดใหญ่ที่มี components จำนวนมาก
สรุป
ในบทนี้ เราได้เรียนรู้เกี่ยวกับการสร้าง HTML Templates ด้วย <template> tag และการใช้ JavaScript เพื่อ clone และ inject templates นอกจากนี้ เรายังได้เรียนรู้เกี่ยวกับการสร้าง Reusable HTML Components ด้วย Custom Elements ซึ่งเป็นเทคนิคสำคัญในการพัฒนาเว็บไซต์ขนาดใหญ่ ที่จะช่วยให้โค้ดของเราเป็นระเบียบ อ่านง่าย และสามารถนำกลับมาใช้ใหม่ได้หลายครั้ง ในบทถัดไป เราจะมาเรียนรู้เกี่ยวกับ HTML Canvas เบื้องต้น ซึ่งเป็น API ที่ใช้สำหรับวาดกราฟิกบนหน้าเว็บ