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

โหมด Open และ Closed

เมื่อเรียก attachShadow คุณต้องระบุ mode เป็น 'open' หรือ 'closed' ซึ่งกำหนดว่า JavaScript ภายนอกจะเข้าถึง shadow root ผ่าน .shadowRoot property ได้หรือไม่

โหมดelement.shadowRoot คืนค่าใช้เมื่อ
openshadow root objectทั่วไป — DevTools, tests, Lit ต้องการ
closednullต้องการซ่อน internal จาก JS ภายนอก

ด้วยโหมด open shadow root จะเข้าถึงได้จากภายนอก component:

var el = document.querySelector('open-box');
console.log(el.shadowRoot); // ShadowRoot object

ซึ่งทำให้ DevTools, test frameworks และ libraries อย่าง Lit สามารถ inspect และ interact กับ shadow tree ได้

ด้วยโหมด closed property .shadowRoot จะคืนค่า null สำหรับ JavaScript ภายนอก:

var el = document.querySelector('closed-box');
console.log(el.shadowRoot); // null

shadow root ยังคงอยู่ภายใน — component เองก็ยังเข้าถึงได้ผ่าน variable ที่เก็บค่าที่ attachShadow คืนมา แต่โค้ดภายนอกไม่สามารถเข้าถึงได้ผ่าน .shadowRoot

ตัวเลือกBenefitCost
mode: 'open'DevTools, test frameworks และ library อย่าง Lit เข้าถึง shadowRoot ได้ตามปกติ ใช้งานง่าย debug ง่ายinternal structure เข้าถึงได้จาก JavaScript ภายนอกทั้งหมด ไม่มีการซ่อนจริง
mode: 'closed'.shadowRoot คืนค่า null จากภายนอก ให้ความรู้สึกว่า internal ถูกซ่อนเขียน test และ debug ยากขึ้นมาก เครื่องมือ inspect มาตรฐานเข้าไม่ถึง และไม่ได้เป็น security boundary จริง
  • เลือก mode: 'closed' เพราะคิดว่าปลอดภัยกว่า — closed mode แค่ซ่อน reference จาก .shadowRoot แต่ยังตรวจสอบ DOM ผ่าน document.querySelector และ dev tools บางส่วนได้อยู่ดี ไม่ใช่ security boundary จริง อย่าใช้แทนการป้องกันข้อมูลจริง
  • ใช้ mode: 'closed' แล้วลืมเก็บ reference ของ shadow root ไว้เอง — เพราะ this.shadowRoot จะเป็น null ต้องเก็บค่าที่ attachShadow คืนมาไว้ใน variable หรือ private field ของ instance เอง
  • เลือก closed mode โดยไม่คิดถึง tooling — test frameworks, DevTools inspector และ library หลายตัว (เช่น Lit) คาดหวัง mode: 'open' การเลือก closed โดยไม่จำเป็นทำให้ debug และ test component ยากขึ้นโดยไม่ได้อะไรกลับมาคุ้มค่า

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

Salesforce Lightning (LWC) — เลือกใช้ mode: 'open' เป็นค่าเริ่มต้นสำหรับ component เพื่อให้ DevTools และ automated test เข้าถึง shadow tree ได้ในระดับ enterprise

YouTube — video player component ใช้ mode: 'open' เพื่อให้ยังคง debug และ inspect ได้ผ่าน DevTools แม้จะ encapsulate style และ DOM ไว้

`element.shadowRoot` คืนค่าอะไรเมื่อแนบ shadow root ด้วย `mode: "closed"`?
โหมดใดที่แนะนำสำหรับคอมโพเนนต์ที่ต้องทำงานร่วมกับ DevTools ของ browser และเฟรมเวิร์กทดสอบ?
เมื่อใช้ `mode: "closed"` จะเก็บ reference ไปยัง shadow root ไว้ใช้ภายในคอมโพเนนต์ได้อย่างไร?