0Pricing
JavaScript Academy · บทเรียน

Shadow DOM และการห่อหุ้ม

แยกสไตล์และมาร์กอัปไว้ในรากเงา

Shadow DOM และการห่อหุ้ม เป็นบทเรียน JavaScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน JavaScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

DOM เงาคืออะไร

DOM เงาจะมอบต้นไม้ DOM ส่วนตัวที่ห่อหุ้มไว้ให้แก่องค์ประกอบ มาร์กอัปและสไตล์ภายในจะแยกออกจากส่วนอื่นของหน้า

  • CSS จากภายนอกจะไม่รั่วไหลเข้ามา
  • CSS ภายในจะไม่รั่วไหลออกไป
  • โครงสร้างภายในจะไม่ปรากฏในการค้นหา DOM ตามปกติ

attachShadow

คุณสร้างต้นไม้เงาได้โดยเรียก this.attachShadow({ mode: 'open' }) ซึ่งจะส่งคืน shadow root ที่คุณเติมเนื้อหาได้เหมือนโหนดทั่วไป

class FancyBox extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }
}
customElements.define('fancy-box', FancyBox);

โหมดเปิดเทียบกับโหมดปิด

ตัวเลือก mode ควบคุมการเข้าถึงจากภายนอก:

  • 'open' — เข้าถึง root ได้ผ่าน element.shadowRoot
  • 'closed' — element.shadowRoot ส่งคืนค่า null มีเพียงโค้ดของคุณเท่านั้นที่ถือข้อมูลอ้างอิงไว้

คอมโพเนนต์ส่วนใหญ่ใช้ 'open' เพื่อให้แก้ไขข้อผิดพลาดได้ง่ายขึ้น

const root = this.attachShadow({ mode: 'open' });
// Later, from outside:
// myEl.shadowRoot  -> the shadow root (open)
// closed mode would give null here

การเติมเนื้อหาใน Shadow Root

กำหนดค่าให้ shadowRoot.innerHTML เพื่อสร้างเนื้อหาที่ห่อหุ้มไว้ มาร์กอัปนี้จะมองไม่เห็นสำหรับ document.querySelector

class FancyBox extends HTMLElement {
  constructor() {
    super();
    const root = this.attachShadow({ mode: 'open' });
    root.innerHTML = '<p>I live inside the shadow DOM</p>';
  }
}
customElements.define('fancy-box', FancyBox);

สไตล์ตามขอบเขต

แท็ก style ภายใน shadow root จะมีผลกับ root นั้นเท่านั้น ตัวเลือกเดียวกันภายนอกคอมโพเนนต์จะไม่ได้รับผลกระทบ และสไตล์ของหน้าจะไม่รั่วไหลเข้ามา

root.innerHTML =
  '<style>p { color: rebeccapurple; }</style>' +
  '<p>Only this paragraph is purple.</p>';
// A <p> elsewhere on the page is NOT affected.

ตัวเลือก :host

ภายในสไตล์ของ DOM เงา :host จะเลือกองค์ประกอบกำหนดเองนั้นเอง ซึ่งเป็นโฮสต์ของต้นไม้เงา ใช้ตัวเลือกนี้เพื่อกำหนดสไตล์ให้กับกรอบภายนอกของคอมโพเนนต์

root.innerHTML =
  '<style>' +
  ':host { display: block; border: 1px solid gray; }' +
  ':host(.active) { border-color: green; }' +
  '</style>' +
  '<slot></slot>';

การแยกสไตล์ในการใช้งานจริง

การห่อหุ้มทำให้ผู้สร้างคอมโพเนนต์และผู้สร้างหน้าหยุดแย่งกันใช้ชื่อคลาส กฎ .title ภายในคอมโพเนนต์หนึ่งจะไม่มีผลต่อ .title ที่อื่น

  • ไม่มีการชนกันของ CSS ระดับส่วนกลาง
  • ตัวเลือกที่เรียบง่ายและใช้ได้ทั่วไปกลับมาปลอดภัยอีกครั้ง

การค้นหาภายใน Shadow Root

หากต้องการเข้าถึงโหนดภายใน ให้ค้นหาจาก shadow root ไม่ใช่จากเอกสาร shadow root รองรับเมธอดการค้นหาแบบเดียวกัน

class ToggleButton extends HTMLElement {
  constructor() {
    super();
    const root = this.attachShadow({ mode: 'open' });
    root.innerHTML = '<button>Off</button>';
    this.btn = root.querySelector('button');
  }
}
customElements.define('toggle-button', ToggleButton);

เหตุการณ์ข้ามขอบเขต

เหตุการณ์จำนวนมาก (เช่น click) จะลอยออกจาก DOM เงา แต่จะถูกเปลี่ยนเป้าหมาย เพื่อให้ตัวรับฟังเหตุการณ์ภายนอกเห็นองค์ประกอบโฮสต์ ไม่ใช่โหนดภายใน วิธีนี้ช่วยรักษาการห่อหุ้มไว้

// Outside listener sees event.target as <toggle-button>,
// not the inner <button>.
document.querySelector('toggle-button')
  .addEventListener('click', e => {
    console.log(e.target.tagName); // TOGGLE-BUTTON
  });

สไตล์ที่สืบทอดได้

คุณสมบัติ CSS บางรายการ (เช่น color และ font-family) สืบทอดผ่านขอบเขตเงาได้ เนื่องจากการสืบทอดไหลลงมาตามต้นไม้ที่ประกอบขึ้น คุณสามารถเลือกให้รูปลักษณ์สอดคล้องกับหน้าได้โดยอาศัยการสืบทอดหรือใช้คุณสมบัติแบบกำหนดเองของ CSS

// :host { color: inherit; }
// CSS custom properties also pierce the boundary:
// :host { color: var(--text-color, black); }

ควรใช้ DOM เงาเมื่อใด

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

ตรวจสอบความเข้าใจ

ทดสอบความเข้าใจของคุณเกี่ยวกับ DOM เงา

ทบทวน

คุณได้เรียนรู้เกี่ยวกับ DOM เงาดังนี้

  • attachShadow({ mode }) สร้างต้นไม้ที่แยกออกมา
  • 'open' เปิดเผย shadowRoot ส่วน 'closed' จะซ่อนไว้
  • แท็ก style ภายในมีขอบเขตของตนเอง ส่วน :host ใช้กำหนดสไตล์ให้ตัวองค์ประกอบเอง
  • การค้นหาจะทำกับ shadow root ไม่ใช่กับเอกสาร
  • เหตุการณ์จะถูกเปลี่ยนเป้าหมายเพื่อรักษาการห่อหุ้ม

ถัดไป เราจะนำมาร์กอัปกลับมาใช้ใหม่ด้วยเทมเพลตและ slot

คำถามที่พบบ่อย

บทเรียน “Shadow DOM และการห่อหุ้ม” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “Shadow DOM และการห่อหุ้ม” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส JavaScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “Shadow DOM และการห่อหุ้ม”

แยกสไตล์และมาร์กอัปไว้ในรากเงา คุณปฏิบัติ JavaScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน JavaScript Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน JavaScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “Shadow DOM และการห่อหุ้ม” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน JavaScript Academy นี้ได้ไหม

ได้ บทเรียน JavaScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การกำหนดองค์ประกอบกำหนดเอง
  2. การเรียกกลับตามวงจรชีวิต
  3. Shadow DOM และการห่อหุ้ม
  4. แม่แบบและสล็อต
← กลับไปที่ JavaScript Academy