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

attachShadow และ Shadow Root

สร้างต้นไม้เงาที่ห่อหุ้มบนองค์ประกอบโฮสต์

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

DOM แบบเงาคืออะไร

DOM แบบเงาทำให้องค์ประกอบมีโครงสร้าง DOM ของตนเองที่แยกออกจากกัน (เรียกว่า "โครงสร้างเงา") ซึ่งไม่ปรากฏใน DOM หลักของหน้า CSS ภายนอกจะไม่รั่วไหลเข้ามา และ CSS ภายในจะไม่รั่วไหลออกไป — จึงเหมาะอย่างยิ่งสำหรับการห่อหุ้มองค์ประกอบ

การเชื่อมราก DOM แบบเงา

เรียก this.attachShadow({ mode: "open" }) จากตัวสร้างหรือ connectedCallback ขององค์ประกอบกำหนดเอง เมธอดนี้จะคืนค่า ShadowRoot ซึ่งคุณสามารถเติมข้อมูลได้เช่นเดียวกับโครงสร้าง DOM ปกติด้วย innerHTML, appendChild และอื่น ๆ

class MyCard extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: "open" });
    shadow.innerHTML = "<style>p{color:red}</style><p>Hello</p>";
  }
}

โหมดเปิดและโหมดปิด

mode: "open" จะเปิดเผยโครงสร้างเงาผ่าน element.shadowRoot ส่วน mode: "closed" จะซ่อนโครงสร้างนี้ — element.shadowRoot จะคืนค่า null ดังนั้นสคริปต์ภายนอกจึงเข้าไปในโครงสร้างไม่ได้ ในทางปฏิบัติโหมดปิดมีประโยชน์ไม่บ่อยนัก เพราะโค้ดเดียวกับที่กำหนดองค์ประกอบยังสามารถเก็บการอ้างอิงของตนเองไว้ได้

การห่อหุ้มสไตล์

สไตล์ที่กำหนดไว้ภายในโครงสร้างเงา (ผ่าน <style> หรือสไตล์ชีตที่รับมาใช้) จะมีผลเฉพาะภายในโครงสร้างเงานั้น ตัวเลือก CSS ในเอกสารหลักจะไม่ตรงกับโหนดลูกในโครงสร้างเงา และสไตล์ของโครงสร้างเงาจะไม่ข้ามออกมายังเอกสาร

ตัวเลือก :host

จากภายในโครงสร้างเงา องค์ประกอบโฮสต์ (องค์ประกอบกำหนดเองนั้นเอง) จะถูกเลือกด้วยคลาสเทียมพิเศษ :host โดย :host(.large) จะตรงกันเมื่อโฮสต์มีคลาส .large และ :host([disabled]) จะตรงกันเมื่อโฮสต์มีแอตทริบิวต์ disabled

:host {
  display: block;
  padding: 16px;
  border: 1px solid #ccc;
}
:host([disabled]) {
  opacity: 0.5;
  pointer-events: none;
}

การแสดงผลแบบบล็อกขององค์ประกอบกำหนดเอง

องค์ประกอบกำหนดเองมีค่าเริ่มต้นเป็น display: inline ภายในรากเงา ให้ใช้ :host { display: block } เพื่อให้องค์ประกอบทำงานเหมือนองค์ประกอบระดับบล็อก การลืมตั้งค่านี้เป็นสาเหตุที่พบบ่อยของข้อผิดพลาดประเภท "เหตุใด width: 100% ของฉันจึงถูกละเว้น"

การประกอบเหตุการณ์

เหตุการณ์ที่แพร่กระจายออกจากโครงสร้างเงาจะถูก เปลี่ยนเป้าหมาย ที่โฮสต์ การคลิกปุ่มด้านในจะมาถึงตัวรับฟังภายนอกโดยมี event.target === host ใช้ event.composedPath() เพื่อดูเป้าหมายจริงภายใน หากต้องการข้อมูลดังกล่าว

composed: true สำหรับเหตุการณ์กำหนดเอง

เหตุการณ์กำหนดเองที่ส่งออกภายในรูทเงาจะไม่ข้ามขอบเขต เว้นแต่คุณจะสร้างเหตุการณ์เหล่านั้นด้วยทั้ง bubbles: true และ composed: true หากไม่มี composed ตัวรับฟังเหตุการณ์ภายนอกที่โฮสต์จะไม่เห็นเหตุการณ์นั้นเลย

สคริปต์ไม่สามารถรั่วไหลเข้าไปได้

สคริปต์ภายนอกสามารถค้นหาองค์ประกอบโฮสต์ได้ แต่ค้นหาลูกหลานในรูทเงาไม่ได้ document.querySelector("my-card span") จะไม่ส่งคืนสิ่งใด หาก <span> อยู่ภายในทรีเงา การห่อหุ้มช่วยป้องกันไม่ให้ส่วนภายในเกิดการพึ่งพากันโดยไม่ตั้งใจ

DOM เงาแบบประกาศ

เมื่อมี <template shadowrootmode="open"> อยู่ภายใน HTML ขององค์ประกอบ เบราว์เซอร์จะสร้างทรีเงาขณะวิเคราะห์โครงสร้าง โดยไม่ต้องใช้ JavaScript วิธีนี้ทำให้คอมโพเนนต์ที่เรนเดอร์จากเซิร์ฟเวอร์รองรับการเติมข้อมูลหลังโหลดได้ดี เพราะทรีเงามีอยู่ก่อนที่ JS จะเริ่มทำงาน

ข้อควรพิจารณาด้านประสิทธิภาพ

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

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

โหมด open ทำอะไรได้บ้างที่โหมด closed ทำไม่ได้

สรุป

attachShadow({ mode: "open" }) สร้างทรีย่อยของ DOM ที่แยกออกจากกัน โดย CSS และ ID จะไม่รั่วไหลเข้าไปหรือออกมา จัดสไตล์โฮสต์ด้วย :host อย่าลืมกำหนด display: block และใช้ composed: true กับเหตุการณ์ที่ต้องการให้หลุดออกจากขอบเขต มิฉะนั้นทรีเงาจะทำงานเหมือน DOM ปกติ — innerHTML, appendChild และ querySelector ล้วนทำงานภายในทรีได้ตามปกติ

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

บทเรียน “attachShadow และ Shadow Root” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “attachShadow และ Shadow Root”

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

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

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

บทเรียน “attachShadow และ Shadow Root” ใช้เวลานานแค่ไหน

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

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

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

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

  1. attachShadow และ Shadow Root
  2. องค์ประกอบ Slot สำหรับการกระจายเนื้อหา
  3. สไตล์แบบจำกัดขอบเขตภายใน Shadow DOM
  4. Part และ Exportparts สำหรับการกำหนดรูปแบบภายนอก
← กลับไปที่ HTML Academy