Observed Attributes
การประกาศ attribute ที่ต้องการตรวจสอบ
หัวข้อที่มีชื่อว่า “การประกาศ attribute ที่ต้องการตรวจสอบ”Browser จะติดตามเฉพาะ attribute ที่คุณระบุอย่างชัดเจนเท่านั้น static getter observedAttributes ต้องคืนค่าเป็น array ของชื่อ attribute:
static get observedAttributes() { return ['color', 'label'];}เฉพาะ attribute ที่อยู่ใน array นี้เท่านั้นที่จะทำให้ attributeChangedCallback ถูกเรียก หาก array ว่างเปล่า หรือไม่มี getter นี้เลย การเปลี่ยนแปลง attribute จะถูกเพิกเฉยโดยไม่มีข้อผิดพลาด
Signature ของ attributeChangedCallback
หัวข้อที่มีชื่อว่า “Signature ของ attributeChangedCallback”เมื่อ attribute ที่ถูกตรวจสอบมีการเพิ่ม, เปลี่ยนแปลง หรือลบออก browser จะเรียก:
attributeChangedCallback(name, oldValue, newValue) { // name — ชื่อ attribute เช่น 'color' // oldValue — ค่าเดิมเป็น string หรือ null เมื่อตั้งค่าครั้งแรก // newValue — ค่าใหม่เป็น string หรือ null เมื่อถูกลบออก}พารามิเตอร์ทั้งสามเป็น string (หรือ null) เมื่อตั้งค่า attribute เป็นครั้งแรก oldValue จะเป็น null เมื่อลบ attribute ด้วย removeAttribute แล้ว newValue จะเป็น null
รูปแบบที่สมบูรณ์
หัวข้อที่มีชื่อว่า “รูปแบบที่สมบูรณ์”class AttrColor extends HTMLElement { static get observedAttributes() { return ['color', 'label']; }
connectedCallback() { this._render(); }
attributeChangedCallback(name, oldValue, newValue) { this._render(); }
_render() { var color = this.getAttribute('color') || '#6366f1'; var label = this.getAttribute('label') || '?'; this.innerHTML = '<span style="' + 'display:inline-block;' + 'padding:.25rem .75rem;' + 'border-radius:9999px;' + 'background:' + color + ';' + 'color:#fff;' + 'font-weight:600;' + 'font-family:sans-serif;' + 'font-size:.875rem' + '">' + label + '</span>'; }}
customElements.define('attr-color', AttrColor);เดโมใช้งานจริง
หัวข้อที่มีชื่อว่า “เดโมใช้งานจริง”ลองแก้ไข color="#4f46e5" เป็นค่าสี CSS อื่น หรือเปลี่ยนข้อความ label ในแผง HTML — badge จะ render ใหม่ทันที
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
ใช้ observedAttributes + attributeChangedCallback | Reactive ต่อการเปลี่ยน attribute จากภายนอกโดยอัตโนมัติ (เช่น จาก framework หรือ dev tools) เหมาะกับ declarative API | ต้อง parse ค่า string เองทุกครั้ง และเสี่ยง render ซ้ำถ้าไม่เช็ค oldValue/newValue ก่อน |
| ให้ผู้ใช้เรียก method/setter แทนการตั้ง attribute | ควบคุม type ได้ตรงกว่า (ไม่ใช่ string เสมอ) และไม่ต้อง re-render ทุกครั้งที่ attribute เปลี่ยน | ไม่ reactive ต่อการแก้ attribute ตรงๆ ใน HTML หรือ dev tools ผู้ใช้ต้องรู้ API เฉพาะของ element |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- ลืมประกาศ static
observedAttributes— ถ้าไม่มี getter นี้ หรือคืนค่า array ว่างattributeChangedCallbackจะไม่ถูกเรียกเลยไม่ว่า attribute จะเปลี่ยนกี่ครั้งก็ตาม โดยไม่มี error แจ้งเตือน ทำให้ debug ยาก - ลืมว่า
observedAttributesเป็น static — ต้องประกาศเป็นstatic get observedAttributes()ไม่ใช่ instance method ถ้าใส่ผิดที่ getter จะไม่ถูกเรียกและพฤติกรรมจะเหมือนไม่ได้ประกาศเลย - ไม่เช็คว่า
oldValue === newValueก่อน re-render — บางกรณี browser อาจเรียกattributeChangedCallbackแม้ค่าจะไม่เปลี่ยนจริง (เช่นตอนconnectedCallbacksync ค่าเริ่มต้น) การ render โดยไม่เช็คก่อนจะทำให้เปลือง CPU โดยไม่จำเป็น
💡 ตัวอย่างจากของจริง
GitHub — element
<relative-time>ใช้attributeChangedCallbackเพื่อ re-render ข้อความเมื่อ attributedatetimeถูกอัปเดตจาก server-rendered HTML หรือ JavaScript ภายนอกShoelace / Web Awesome — design system component library ใช้
observedAttributesอย่างกว้างขวางเพื่อให้ property ของ component (เช่นsize,variant,disabled) sync กับ attribute ใน HTML ได้แบบ two-way โดยอัตโนมัติ