ไทย

สำรวจพลังของ Web Components โดยเน้นที่ Custom Elements สำหรับการสร้าง UI คอมโพเนนต์ที่นำกลับมาใช้ใหม่ได้และมีการห่อหุ้ม (encapsulated) สำหรับเว็บแอปพลิเคชันต่างๆ

Web Components: เจาะลึก Custom Elements

Web Components ถือเป็นความก้าวหน้าที่สำคัญในการพัฒนาเว็บ โดยนำเสนอวิธีที่เป็นมาตรฐานในการสร้าง UI คอมโพเนนต์ที่สามารถนำกลับมาใช้ใหม่ได้และมีการห่อหุ้ม (encapsulated) ในบรรดาเทคโนโลยีหลักที่ประกอบกันเป็น Web Components นั้น Custom Elements โดดเด่นในฐานะรากฐานสำหรับการกำหนดแท็ก HTML ใหม่ที่มีพฤติกรรมและการเรนเดอร์ที่กำหนดเอง คู่มือฉบับสมบูรณ์นี้จะเจาะลึกถึงความซับซ้อนของ Custom Elements สำรวจประโยชน์ การนำไปใช้ และแนวทางปฏิบัติที่ดีที่สุดสำหรับการสร้างเว็บแอปพลิเคชันที่ทันสมัย

Web Components คืออะไร?

Web Components คือชุดของมาตรฐานเว็บที่ช่วยให้นักพัฒนาสามารถสร้างองค์ประกอบ HTML ที่สามารถนำกลับมาใช้ใหม่ได้ มีการห่อหุ้ม และทำงานร่วมกันได้ โดยนำเสนอแนวทางแบบโมดูลสำหรับการพัฒนาเว็บ ทำให้สามารถสร้าง UI คอมโพเนนต์ที่กำหนดเองซึ่งสามารถแชร์และนำกลับมาใช้ใหม่ได้อย่างง่ายดายในโปรเจกต์และเฟรมเวิร์กต่างๆ เทคโนโลยีหลักที่อยู่เบื้องหลัง Web Components ได้แก่:

ทำความเข้าใจ Custom Elements

Custom Elements เป็นหัวใจสำคัญของ Web Components ที่ช่วยให้นักพัฒนาสามารถขยายคำศัพท์ HTML ด้วยองค์ประกอบของตนเองได้ องค์ประกอบที่กำหนดเองเหล่านี้ทำงานเหมือนกับองค์ประกอบ HTML มาตรฐาน แต่สามารถปรับแต่งให้เข้ากับความต้องการของแอปพลิเคชันโดยเฉพาะได้ ทำให้มีความยืดหยุ่นและการจัดระเบียบโค้ดที่ดียิ่งขึ้น

การกำหนด Custom Elements

ในการกำหนด custom element คุณต้องใช้เมธอด customElements.define() เมธอดนี้รับอาร์กิวเมนต์สองตัว:

  1. ชื่อของ element: สตริงที่แสดงชื่อของ custom element ชื่อจะต้องมีเครื่องหมายขีดกลาง (-) เพื่อหลีกเลี่ยงความขัดแย้งกับองค์ประกอบ HTML มาตรฐาน ตัวอย่างเช่น my-element เป็นชื่อที่ถูกต้อง แต่ myelement ไม่ใช่
  2. คลาสของ element: คลาส JavaScript ที่ขยาย (extends) HTMLElement และกำหนดพฤติกรรมของ custom element

นี่คือตัวอย่างพื้นฐาน:

class MyElement extends HTMLElement {
  constructor() {
    super();
    this.innerHTML = 'Hello, World!';
  }
}

customElements.define('my-element', MyElement);

ในตัวอย่างนี้ เราได้กำหนด custom element ชื่อ my-element คลาส MyElement ขยาย HTMLElement และตั้งค่า inner HTML ของ element เป็น "Hello, World!" ใน constructor

Custom Element Lifecycle Callbacks

Custom element มี lifecycle callbacks หลายอย่างที่ให้คุณสามารถรันโค้ดในขั้นตอนต่างๆ ของวงจรชีวิตของ element ได้ callbacks เหล่านี้เปิดโอกาสให้เริ่มต้นการทำงานของ element, ตอบสนองต่อการเปลี่ยนแปลง attribute, และล้างทรัพยากรเมื่อ element ถูกลบออกจาก DOM

นี่คือตัวอย่างที่สาธิตการใช้ lifecycle callbacks:

class MyElement extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({mode: 'open'});
  }

  connectedCallback() {
    this.shadow.innerHTML = `

Connected to the DOM!

`; console.log('Element connected'); } disconnectedCallback() { console.log('Element disconnected'); } static get observedAttributes() { return ['data-message']; } attributeChangedCallback(name, oldValue, newValue) { if (name === 'data-message') { this.shadow.innerHTML = `

${newValue}

`; } } } customElements.define('my-element', MyElement);

ในตัวอย่างนี้ connectedCallback() จะแสดงข้อความในคอนโซลและตั้งค่า inner HTML ของ element เมื่อมันถูกเชื่อมต่อกับ DOM ส่วน disconnectedCallback() จะแสดงข้อความเมื่อ element ถูกตัดการเชื่อมต่อ และ attributeChangedCallback() จะถูกเรียกเมื่อ attribute data-message เปลี่ยนแปลง ซึ่งจะอัปเดตเนื้อหาของ element ตามนั้น ส่วน observedAttributes getter จะระบุว่าเราต้องการสังเกตการณ์การเปลี่ยนแปลงของ attribute data-message

การใช้ Shadow DOM เพื่อการห่อหุ้ม (Encapsulation)

Shadow DOM ให้การห่อหุ้มสำหรับ web components ทำให้คุณสามารถสร้าง DOM tree แยกต่างหากสำหรับคอมโพเนนต์ซึ่งถูกแยกออกจากส่วนที่เหลือของหน้าเว็บ ซึ่งหมายความว่าสไตล์และสคริปต์ที่กำหนดไว้ภายใน Shadow DOM จะไม่ส่งผลกระทบต่อส่วนที่เหลือของหน้า และในทางกลับกัน การห่อหุ้มนี้ช่วยป้องกันความขัดแย้งและทำให้แน่ใจว่าคอมโพเนนต์ของคุณทำงานได้อย่างคาดเดาได้

ในการใช้ Shadow DOM คุณสามารถเรียกเมธอด attachShadow() บน element ได้ เมธอดนี้รับออบเจกต์ตัวเลือกที่ระบุโหมดของ Shadow DOM โดย mode สามารถเป็นได้ทั้ง 'open' หรือ 'closed' หากโหมดเป็น 'open' จะสามารถเข้าถึง Shadow DOM จาก JavaScript ได้โดยใช้คุณสมบัติ shadowRoot ของ element หากโหมดเป็น 'closed' จะไม่สามารถเข้าถึง Shadow DOM จาก JavaScript ได้

นี่คือตัวอย่างที่สาธิตการใช้ Shadow DOM:

class MyElement extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({ mode: 'open' });
    this.shadow.innerHTML = `
      
      

This is inside the Shadow DOM.

`; } } customElements.define('my-element', MyElement);

ในตัวอย่างนี้ เราแนบ Shadow DOM เข้ากับ element ด้วย mode: 'open' จากนั้นเราตั้งค่า inner HTML ของ Shadow DOM ให้มีสไตล์ที่กำหนดสีของย่อหน้าเป็นสีน้ำเงินและองค์ประกอบย่อหน้าพร้อมข้อความบางส่วน สไตล์ที่กำหนดไว้ภายใน Shadow DOM จะมีผลกับองค์ประกอบภายใน Shadow DOM เท่านั้น และจะไม่ส่งผลกระทบต่อย่อหน้าที่อยู่นอก Shadow DOM

ประโยชน์ของการใช้ Custom Elements

Custom Elements มีประโยชน์หลายประการสำหรับการพัฒนาเว็บ:

ตัวอย่างการใช้งานจริงของ Custom Elements

เรามาสำรวจตัวอย่างการใช้งานจริงของ Custom Elements ในการสร้าง UI คอมโพเนนต์ทั่วไปกัน

คอมโพเนนต์ตัวนับอย่างง่าย

ตัวอย่างนี้สาธิตวิธีการสร้างคอมโพเนนต์ตัวนับอย่างง่ายโดยใช้ Custom Elements

class Counter extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({ mode: 'open' });
    this._count = 0;
    this.render();
  }

  connectedCallback() {
    this.shadow.querySelector('.increment').addEventListener('click', () => {
      this.increment();
    });
    this.shadow.querySelector('.decrement').addEventListener('click', () => {
      this.decrement();
    });
  }

  increment() {
    this._count++;
    this.render();
  }

  decrement() {
    this._count--;
    this.render();
  }

  render() {
    this.shadow.innerHTML = `
      
      
${this._count}
`; } } customElements.define('my-counter', Counter);

โค้ดนี้กำหนดคลาส Counter ที่ขยาย HTMLElement constructor จะเริ่มต้นการทำงานของคอมโพเนนต์, แนบ Shadow DOM, และตั้งค่าการนับเริ่มต้นเป็น 0 เมธอด connectedCallback() จะเพิ่ม event listeners ให้กับปุ่มเพิ่มและลดค่า เมธอด increment() และ decrement() จะอัปเดตค่าการนับและเรียกเมธอด render() เพื่ออัปเดตการแสดงผลของคอมโพเนนต์ เมธอด render() จะตั้งค่า inner HTML ของ Shadow DOM ให้รวมถึงการแสดงผลตัวนับและปุ่มต่างๆ

คอมโพเนนต์ Image Carousel

ตัวอย่างนี้สาธิตวิธีการสร้างคอมโพเนนต์ image carousel โดยใช้ Custom Elements เพื่อความกระชับ แหล่งที่มาของรูปภาพเป็นเพียงตัวยึดตำแหน่งและสามารถโหลดแบบไดนามิกจาก API, CMS, หรือ local storage ได้ สไตล์ลิ่งก็ถูกย่อให้เหลือน้อยที่สุดเช่นกัน

class ImageCarousel extends HTMLElement {
 constructor() {
  super();
  this.shadow = this.attachShadow({ mode: 'open' });
  this._images = [
  'https://via.placeholder.com/350x150',
  'https://via.placeholder.com/350x150/0077bb',
  'https://via.placeholder.com/350x150/00bb77',
  ];
  this._currentIndex = 0;
  this.render();
 }

 connectedCallback() {
  this.shadow.querySelector('.prev').addEventListener('click', () => {
  this.prevImage();
  });
  this.shadow.querySelector('.next').addEventListener('click', () => {
  this.nextImage();
  });
 }

 nextImage() {
  this._currentIndex = (this._currentIndex + 1) % this._images.length;
  this.render();
 }

 prevImage() {
  this._currentIndex = (this._currentIndex - 1 + this._images.length) % this._images.length;
  this.render();
 }

 render() {
  this.shadow.innerHTML = `
  
  
  `;
 }
}

customElements.define('image-carousel', ImageCarousel);

โค้ดนี้กำหนดคลาส ImageCarousel ที่ขยาย HTMLElement constructor จะเริ่มต้นการทำงานของคอมโพเนนต์, แนบ Shadow DOM, และตั้งค่าอาร์เรย์รูปภาพเริ่มต้นและดัชนีปัจจุบัน เมธอด connectedCallback() จะเพิ่ม event listeners ให้กับปุ่มก่อนหน้าและถัดไป เมธอด nextImage() และ prevImage() จะอัปเดตดัชนีปัจจุบันและเรียกเมธอด render() เพื่ออัปเดตการแสดงผลของคอมโพเนนต์ เมธอด render() จะตั้งค่า inner HTML ของ Shadow DOM ให้รวมถึงรูปภาพปัจจุบันและปุ่มต่างๆ

แนวทางปฏิบัติที่ดีที่สุดสำหรับการทำงานกับ Custom Elements

นี่คือแนวทางปฏิบัติที่ดีที่สุดที่ควรปฏิบัติตามเมื่อทำงานกับ Custom Elements:

Custom Elements และ Frameworks

Custom Elements ถูกออกแบบมาให้ทำงานร่วมกับเทคโนโลยีเว็บและเฟรมเวิร์กอื่นๆ ได้ สามารถใช้ร่วมกับเฟรมเวิร์กยอดนิยมอย่าง React, Angular, และ Vue.js

การใช้ Custom Elements ใน React

ในการใช้ Custom Elements ใน React คุณสามารถเรนเดอร์พวกมันได้เหมือนกับองค์ประกอบ HTML อื่นๆ อย่างไรก็ตาม คุณอาจต้องใช้ ref เพื่อเข้าถึง DOM element ที่อยู่เบื้องหลังและโต้ตอบกับมันโดยตรง

import React, { useRef, useEffect } from 'react';

function MyComponent() {
  const myElementRef = useRef(null);

  useEffect(() => {
    if (myElementRef.current) {
      // Access the custom element's API
      myElementRef.current.addEventListener('custom-event', (event) => {
        console.log('Custom event received:', event.detail);
      });
    }
  }, []);

  return ;
}

export default MyComponent;

ในตัวอย่างนี้ เราใช้ ref เพื่อเข้าถึง custom element my-element และเพิ่ม event listener เข้าไป ซึ่งทำให้เราสามารถ lắng ฟัง custom events ที่ถูกส่งมาจาก custom element และตอบสนองตามนั้นได้

การใช้ Custom Elements ใน Angular

ในการใช้ Custom Elements ใน Angular คุณต้องกำหนดค่า Angular ให้รู้จัก custom element ซึ่งสามารถทำได้โดยการเพิ่ม custom element เข้าไปในอาร์เรย์ schemas ในการกำหนดค่าของโมดูล

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }

เมื่อ custom element ถูกลงทะเบียนแล้ว คุณสามารถใช้มันในเทมเพลต Angular ของคุณได้เหมือนกับองค์ประกอบ HTML อื่นๆ

การใช้ Custom Elements ใน Vue.js

Vue.js ก็รองรับ Custom Elements โดยกำเนิดเช่นกัน คุณสามารถใช้พวกมันได้โดยตรงในเทมเพลตของคุณโดยไม่ต้องมีการกำหนดค่าพิเศษใดๆ



Vue จะจดจำ custom element โดยอัตโนมัติและเรนเดอร์มันอย่างถูกต้อง

ข้อควรพิจารณาด้านการเข้าถึง (Accessibility)

เมื่อสร้าง Custom Elements สิ่งสำคัญคือต้องพิจารณาถึงการเข้าถึงเพื่อให้แน่ใจว่าคอมโพเนนต์ของคุณสามารถใช้งานได้โดยทุกคน รวมถึงผู้พิการด้วย นี่คือข้อควรพิจารณาที่สำคัญด้านการเข้าถึง:

การทำให้เป็นสากล (Internationalization) และการปรับให้เข้ากับท้องถิ่น (Localization)

เมื่อพัฒนา Custom Elements สำหรับผู้ชมทั่วโลก สิ่งสำคัญคือต้องพิจารณาถึงการทำให้เป็นสากล (i18n) และการปรับให้เข้ากับท้องถิ่น (l10n) นี่คือข้อควรพิจารณาที่สำคัญ:

สรุป

Custom Elements เป็นเครื่องมือที่ทรงพลังสำหรับการสร้าง UI คอมโพเนนต์ที่สามารถนำกลับมาใช้ใหม่ได้และมีการห่อหุ้ม มีประโยชน์หลายประการสำหรับการพัฒนาเว็บ รวมถึงการนำกลับมาใช้ใหม่, การห่อหุ้ม, การทำงานร่วมกัน, การบำรุงรักษา, และประสิทธิภาพ โดยการปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดที่ระบุไว้ในคู่มือนี้ คุณสามารถใช้ประโยชน์จาก Custom Elements เพื่อสร้างเว็บแอปพลิเคชันที่ทันสมัย แข็งแกร่ง บำรุงรักษาง่าย และเข้าถึงได้โดยผู้ชมทั่วโลก ในขณะที่มาตรฐานเว็บยังคงพัฒนาต่อไป Web Components รวมถึง Custom Elements จะมีความสำคัญเพิ่มขึ้นเรื่อยๆ สำหรับการสร้างเว็บแอปพลิเคชันแบบโมดูลและปรับขนาดได้

ยอมรับพลังของ Custom Elements เพื่อสร้างอนาคตของเว็บ ทีละคอมโพเนนต์ อย่าลืมพิจารณาถึงการเข้าถึง, การทำให้เป็นสากล, และการปรับให้เข้ากับท้องถิ่น เพื่อให้แน่ใจว่าคอมโพเนนต์ของคุณสามารถใช้งานได้โดยทุกคน ทุกที่