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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- attachShadow และ Shadow Root
- องค์ประกอบ Slot สำหรับการกระจายเนื้อหา
- สไตล์แบบจำกัดขอบเขตภายใน Shadow DOM
- Part และ Exportparts สำหรับการกำหนดรูปแบบภายนอก