ข้ามไปยังเนื้อหา

การนิยาม Element

autonomous custom element ทุกตัวเริ่มต้นจาก ES class ที่ extend HTMLElement:

class HelloBadge extends HTMLElement {
// lifecycle callbacks go here
}

class จะไม่มีชื่อหรือมีชื่อก็ได้ — ชื่อนั้นถูกใช้ภายในโดย JavaScript เท่านั้น ตัวตนสาธารณะของ element คือชื่อ tag ที่คุณลงทะเบียนไว้

เมธอด customElements.define รับอาร์กิวเมนต์ที่จำเป็นสองตัวและอาร์กิวเมนต์เสริมหนึ่งตัว:

customElements.define(tagName, constructor, options);
// ^string ^class ^optional { extends: '...' }
customElements.define('hello-badge', HelloBadge);

หลังจากการเรียกนี้ browser จะรู้ว่า <hello-badge> ทุกตัวในเอกสารคืออินสแตนซ์ของ HelloBadge

ชื่อ tag ของ custom element ต้องมีเครื่องหมายขีด (hyphen) อย่างน้อยหนึ่งตัว นี่คือวิธีที่ browser ใช้แยกแยะ element ของคุณออกจาก element ที่มีมาในตัวทั้งในปัจจุบันและอนาคต:

<!-- valid custom element names -->
<hello-badge></hello-badge>
<my-app></my-app>
<x-button></x-button>
<!-- INVALID — no hyphen — the browser treats these as unknown built-ins -->
<hellobadge></hellobadge>
<mybadge></mybadge>

คำนำหน้าที่สงวนไว้และคุณใช้ไม่ได้: annotation-xml, color-profile, font-face, font-face-*

เมื่อนิยามแล้ว element จะทำงานเหมือน element เนทีฟทุกประการ — วางไว้ในมาร์กอัป กำหนด attribute และ query ด้วย JavaScript ได้เลย:

<hello-badge name="Alice"></hello-badge>
<hello-badge name="Bob"></hello-badge>
const badge = document.querySelector('hello-badge');
badge.getAttribute('name'); // 'Alice'

ลองเปลี่ยนค่า attribute name ในแผง HTML แล้วดูผลลัพธ์อัปเดตตาม

ตัวเลือกBenefitCost
Native custom elements (customElements.define)ไม่ผูกกับเฟรมเวิร์กใด ทำงานได้ทุกที่ที่มี DOM โดยไม่ต้องมี build stepDX ไม่ลื่นไหลเท่าเฟรมเวิร์กอย่าง React/Vue — ไม่มี JSX, ไม่มี reactive state ให้ในตัว ต้องจัดการเอง
ตั้งชื่อ tag ตามกฎ hyphenbrowser แยกแยะ element ของคุณจาก element เนทีฟทั้งปัจจุบันและอนาคตได้ชัดเจนต้องคิดชื่อที่มีขีดเสมอ เพิ่มภาระเล็กน้อยตอนออกแบบ naming convention
  • ตั้งชื่อ tag โดยไม่มีเครื่องหมายขีด — เช่น mybadge browser จะปฏิเสธการลงทะเบียนหรือถือว่าเป็น HTMLUnknownElement แบบเงียบ ๆ
  • เรียก customElements.define() ซ้ำด้วยชื่อ tag เดิม — จะโยน error ทันที ต้องเช็คด้วย customElements.get(tagName) ก่อนถ้าไม่แน่ใจว่าลงทะเบียนไปแล้วหรือยัง
  • ใช้คำนำหน้าที่สงวนไว้ — เช่น font-face-* หรือ annotation-xml จะลงทะเบียนไม่ได้เพราะสเปกกันไว้ให้ใช้ในอนาคต

💡 ตัวอย่างจากของจริง

YouTube — ฟรอนต์เอนด์ทั้งเว็บสร้างขึ้นบน custom elements ภายในระบบของตัวเอง ผ่านการเรียก customElements.define จำนวนมากสำหรับแต่ละ component

GitHub — ลงทะเบียน element อย่าง <relative-time> ด้วยชื่อที่มีขีดตามกฎสเปก แล้วนำไปใช้ตรง ๆ ใน HTML ของหน้าเว็บจริง

ชื่อ tag ใดเป็นชื่อ autonomous custom element ที่ถูกต้อง?
อาร์กิวเมนต์ตัวแรกของ customElements.define คืออะไร?
browser ทำอะไรเมื่อพบชื่อ tag ที่ถูกลงทะเบียนไว้กับ customElements.define แล้ว?