Kodokon kodokon.com

Web Components: कस्टम एलिमेंट, shadow DOM और slots

कस्टम एलिमेंट के जीवनचक्र, shadow DOM एनकैप्सुलेशन और slots के माध्यम से सामग्री प्रोजेक्शन में महारत हासिल करें।

12 मिनट · 3 प्रश्न

इस पाठ को Kodokon में खोलें

Custom elements HTML शब्दावली का विस्तार करते हैं: HTMLElement से विरासत में मिलने वाली कोई भी क्लास CustomElementRegistry में पंजीकृत की जा सकती है, बशर्ते उसके नाम में एक हाइफ़न हो (user-badge, कभी userbadge नहीं)। एक सूक्ष्म बिंदु: यदि टैग दस्तावेज़ में customElements.define कॉल होने से पहले प्रकट होता है, तो इसे पहले एक अज्ञात तत्व के रूप में बनाया जाता है और फिर वहीं upgraded किया जाता है - तब कंस्ट्रक्टर को वृक्ष में पहले से मौजूद एक नोड पर बाद में लागू किया जाता है।

JAVASCRIPT
class UserBadge extends HTMLElement {
  static observedAttributes = ["name"];
  connectedCallback() {
    this.render();
  }
  attributeChangedCallback() {
    this.render();
  }
  render() {
    this.textContent = this.getAttribute("name");
  }
}
customElements.define("user-badge", UserBadge);
एक संपूर्ण जीवनचक्र वाला न्यूनतम कस्टम एलिमेंट।

जीवनचक्र में कुछ जाल छिपे हैं: attributeChangedCallback केवल observedAttributes में सूचीबद्ध एट्रिब्यूट्स के लिए ही सक्रिय होता है, और अपग्रेड के दौरान इसे हर पहले से मौजूद एट्रिब्यूट के लिए connectedCallback से पहले कॉल किया जाता है। विनिर्देश कंस्ट्रक्टर को एट्रिब्यूट्स और चाइल्ड की जाँच करने, या कोई जोड़ने से मना करता है: जिस क्षण यह चलता है (createElement के माध्यम से या क्लोनिंग द्वारा), तत्व पूरी तरह खाली हो सकता है।

HTML
<template id="card-tpl">
  <style>
    :host { display: block; padding: 1rem; }
    ::slotted(h2) { margin: 0; }
  </style>
  <slot name="title"></slot>
  <slot></slot>
</template>
एक निष्क्रिय template: पार्स किया गया, लेकिन न तो निष्पादित और न ही रेंडर किया गया।

attachShadow एक एनकैप्सुलेटेड उप-वृक्ष बनाता है: स्टाइल इससे बाहर नहीं रिसते, पेज के सेलेक्टर इसके अंदर नहीं पहुँचते - केवल विरासत में मिलने वाली CSS प्रॉपर्टीज़ (color, font) और कस्टम प्रॉपर्टीज़ ही सीमा को पार करती हैं। एक <template> की सामग्री एक DocumentFragment में रहती है जो .content के माध्यम से सुलभ है: जब तक आप इसे दस्तावेज़ में क्लोन नहीं करते, तब तक इसकी स्क्रिप्ट नहीं चलतीं और इसकी इमेज लोड नहीं होतीं। light DOM में रखे गए नोड <slot> तत्वों में प्रोजेक्ट किए जाते हैं: वे भौतिक रूप से light DOM में ही रहते हैं, और slotchange इवेंट आपको असाइनमेंट में किसी भी बदलाव की सूचना देता है।

JAVASCRIPT
class InfoCard extends HTMLElement {
  constructor() {
    super();
    const tpl = document.getElementById("card-tpl");
    this.attachShadow({ mode: "open" })
      .appendChild(tpl.content.cloneNode(true));
  }
}
customElements.define("info-card", InfoCard);
template को एक खुली shadow root में क्लोन करना।

दो विस्तार आपके ध्यान के योग्य हैं। Form-associated custom elements: static formAssociated = true और attachInternals() के साथ, आपका कंपोनेंट पूरी तरह से फ़ॉर्म में भाग लेता है (सबमिट किया गया मान, नेटिव वैलिडेशन, :invalid अवस्थाएँ)। और declarative shadow DOM: <template shadowrootmode=open> बिना JavaScript के पार्स समय पर एक shadow root अटैच करता है, जो web components को सर्वर-साइड रेंडरिंग के साथ संगत बनाता है।

ज्ञान जांच

सुनिश्चित करें कि आपको इस पाठ के मुख्य बिंदु याद हैं।

  1. किसी कस्टम एलिमेंट के कंस्ट्रक्टर को न तो अपने एट्रिब्यूट्स पढ़ने चाहिए और न ही चाइल्ड बनाने चाहिए, ऐसा क्यों?
    • क्योंकि connectedCallback से पहले एट्रिब्यूट्स रीड-ओनली के रूप में फ़्रीज़ हो जाते हैं
    • क्योंकि shadow DOM निर्माण के दौरान light DOM को छिपा देता है
    • क्योंकि उस क्षण (createElement, क्लोनिंग) पर तत्व खाली हो सकता है; विनिर्देश एक ऐसे कंस्ट्रक्टर की माँग करता है जिसका सामग्री पर कोई प्रभाव न हो
  2. attachShadow({ mode: 'closed' }) के साथ, बाहर से element.shadowRoot क्या लौटाता है?
    • null: केवल attachShadow द्वारा लौटाया गया संदर्भ ही shadow root तक पहुँच देता है
    • shadow root, लेकिन रीड-ओनली
    • एक खाली DocumentFragment
    • एक DOMException फेंका जाता है
  3. <slot> में प्रोजेक्ट किए गए नोड भौतिक रूप से कहाँ रहते हैं?
    • उन्हें रेंडर समय पर shadow DOM में ले जाया जाता है
    • वे light DOM में ही रहते हैं; slot उन्हें केवल समतल किए गए वृक्ष में अपनी स्थिति पर प्रदर्शित करता है
    • उन्हें क्लोन किया जाता है: मूल light DOM में रहता है, प्रति shadow DOM में रहती है