कस्टम एलिमेंट के लिए सबसे सही तरीके

कस्टम एलिमेंट की मदद से, अपने एचटीएमएल टैग बनाए जा सकते हैं. इस चेकलिस्ट में, अच्छी क्वालिटी के एलिमेंट बनाने के सबसे सही तरीकों के बारे में बताया गया है.

कस्टम एलिमेंट की मदद से, एचटीएमएल का दायरा बढ़ाया जा सकता है और अपने टैग तय किए जा सकते हैं. ये हैं लेकिन यह सुविधा शानदार है, लेकिन ये बेहद निचले लेवल की भी हैं. इसका मतलब यह है कि यह हमेशा साफ़ तौर पर बताना होगा कि आपके एलिमेंट को सबसे अच्छे तरीके से कैसे लागू किया जाए.

इसलिए, हमने आपके लिए यह बेहतर अनुभव दिया है, ताकि आप बेहतरीन अनुभव पा सकें की चेकलिस्ट देखें. यह उन सभी चीज़ों का विश्लेषण करता है, जिनके बारे में हमें लगता है कि इसे अच्छा व्यवहार करने वाला कस्टम एलिमेंट.

चेकलिस्ट

शैडो डीओएम

स्टाइल को इनकैप्सुलेट करने के लिए, शैडो रूट बनाएं.

क्यों? अपने एलिमेंट के शैडो रूट में स्टाइल को इनकैप्सुलेट करने से यह पक्का होता है कि वे सही से काम करेंगे इस्तेमाल किया जा सकता है. यह खास तौर पर तब ज़रूरी होता है, जब डेवलपर आपके तत्व को किसी अन्य तत्व के शैडो रूट में रखना चाहता है. यह किसी चेकबॉक्स या रेडियो बटन जैसे सामान्य एलिमेंट पर भी लागू होता है. यह हो सकता है ऐसा है कि आपके शैडो रूट में सिर्फ़ स्टाइल होंगे खुद को सुरक्षित रखने की कोशिश करते हैं.
उदाहरण <howto-checkbox> एलिमेंट.

कंस्ट्रक्टर में अपना शैडो रूट बनाएं.

क्यों? कंस्ट्रक्टर तब होता है, जब आपके पास एलिमेंट के बारे में खास जानकारी होती है. यह विकल्प सेटअप करने का सही समय है. तो दूसरी चीज़ें ठीक से काम कर रही हैं. इसे बाद के कॉलबैक में करना, जैसे connectedCallback का मतलब है कि आपको इससे बचना होगा ऐसी स्थितियां जिनमें एलिमेंट डिटैच करके, उसे फिर से दस्तावेज़ से जोड़ा जाता है.
उदाहरण <howto-checkbox> एलिमेंट.

जिस चाइल्ड एलिमेंट को बनाना है उसे उसके शैडो रूट में रखें.

क्यों? आपके एलिमेंट से बनाए गए चिल्ड्रेन भी इसके लागू किए जाने का हिस्सा होते हैं. इसलिए, ऐसा होना चाहिए निजी. शैडो रूट की सुरक्षा के बिना, JavaScript के बाहर इन बच्चों के साथ अनजाने में रुकावट पैदा करते हैं.
उदाहरण <howto-tabs> एलिमेंट.

<slot> का इस्तेमाल करो लाइट DOM चिल्ड्रेन को अपने शैडो DOM में प्रोजेक्ट करने के लिए

क्यों? अपने कॉम्पोनेंट के उपयोगकर्ताओं को कॉम्पोनेंट का कॉन्टेंट बताने की अनुमति दें, क्योंकि एचटीएमएल चाइल्ड आपके कॉम्पोनेंट को ज़्यादा कंपोज़ेबल बनाता है. जब कोई ब्राउज़र कस्टम एलिमेंट के साथ काम नहीं करता, तब नेस्ट किया गया कॉन्टेंट उपलब्ध रहता है, दिखता है, और ऐक्सेस किया जा सकता है.
उदाहरण <howto-tabs> एलिमेंट.

:host डिसप्ले स्टाइल सेट करें (जैसे, block, inline-block, flex) अलग से नहीं दिखाएगा, जब तक कि आप इसकी डिफ़ॉल्ट सेटिंग न चाहें inline.

क्यों? कस्टम एलिमेंट डिफ़ॉल्ट रूप से display: inline होते हैं. इसलिए, उन्हें width या height से कोई असर नहीं पड़ेगा. ऐसा अक्सर डेवलपर को चौंकाता है और इसकी वजह से तय करता है. जब तक कि आप inline डिसप्ले पसंद न करें, तब तक आप हमेशा डिफ़ॉल्ट display वैल्यू सेट करनी चाहिए.
उदाहरण <howto-checkbox> एलिमेंट.

:host का डिसप्ले स्टाइल जोड़ें, जो छिपे हुए एट्रिब्यूट के हिसाब से हो.

क्यों? डिफ़ॉल्ट display स्टाइल वाला कस्टम एलिमेंट, जैसे कि :host { display: block }, कम वैल्यू को बदल देगा बिल्ट-इन hidden एट्रिब्यूट. अगर hidden को सेट किया जाता है, तो यह आपको हैरान कर सकता है एट्रिब्यूट का इस्तेमाल करें display: none. इसके अलावा display की डिफ़ॉल्ट स्टाइल का इस्तेमाल करें. hidden के लिए सहायता जोड़ें :host([hidden]) { display: none } के साथ.
उदाहरण <howto-checkbox> एलिमेंट.

एट्रिब्यूट और प्रॉपर्टी

लेखक के सेट, ग्लोबल एट्रिब्यूट को न बदलें.

क्यों? ग्लोबल एट्रिब्यूट वे हैं जो सभी एचटीएमएल एलिमेंट पर मौजूद होते हैं. कुछ सूचनाएं मिल रही हैं उदाहरण के लिए, tabindex और role. कस्टम एलिमेंट अपने शुरुआती tabindex को 0 पर सेट करने के बाद, इसे कीबोर्ड के तौर पर इस्तेमाल किया जा सकता है फ़ोकस करने लायक. लेकिन आपको हमेशा पहले यह जांच करनी चाहिए कि क्या डेवलपर आपके एलिमेंट ने इसकी वैल्यू किसी दूसरी वैल्यू पर सेट की है. उदाहरण के लिए, अगर tabindex से -1 तक, यह इस बात का संकेत है कि वे एलिमेंट इंटरैक्टिव होने चाहिए.
उदाहरण <howto-checkbox> एलिमेंट. इसके बारे में यहां और समझाया गया है पेज लेखक को न बदलें.

हमेशा प्रिमिटिव डेटा (स्ट्रिंग, संख्याएं, बूलियन) को एट्रिब्यूट के रूप में स्वीकार करें या प्रॉपर्टी.

क्यों? कस्टम एलिमेंट, कॉन्फ़िगर किए जा सकने वाले होने चाहिए. जैसे, प्रॉडक्ट में पहले से मौजूद एलिमेंट को कॉन्फ़िगर किया जा सकता है. कॉन्फ़िगरेशन को, एलान के तौर पर, एट्रिब्यूट के ज़रिए या ज़रूरी तौर पर पास किया जा सकता है प्रॉपर्टी के ज़रिए उपलब्ध कराई जाती है. आम तौर पर, हर एट्रिब्यूट को संबंधित प्रॉपर्टी.
उदाहरण <howto-checkbox> एलिमेंट.

शुरुआती डेटा एट्रिब्यूट और प्रॉपर्टी को सिंक में रखने की कोशिश करें. इसमें ये चीज़ें शामिल हैं प्रॉपर्टी को एट्रिब्यूट करना है और एट्रिब्यूट करने के लिए प्रॉपर्टी को एट्रिब्यूट करना है.

क्यों? आपको यह कभी पता नहीं चलता कि उपयोगकर्ता आपके एलिमेंट से कैसे इंटरैक्ट करेगा. वे यह कर सकते थे JavaScript में प्रॉपर्टी सेट करें और फिर उस वैल्यू को पढ़ने की उम्मीद करें getAttribute() जैसे एपीआई का इस्तेमाल करके. अगर हर एट्रिब्यूट में करने के लिए डिज़ाइन किया गया है, और वे दोनों दिखाई देते हैं, तो इससे उपयोगकर्ता आपके एलिमेंट के साथ काम कर सकते हैं. दूसरे शब्दों में, कॉलिंग setAttribute('foo', value) को संबंधित foo गुण और इसके विपरीत. बेशक, ये अपवाद हैं यह नियम. आपको हाई फ़्रीक्वेंसी वाली प्रॉपर्टी नहीं दिखानी चाहिए, जैसे कि वीडियो प्लेयर में currentTime. अपने विवेक का इस्तेमाल करें. अगर यह ऐसा लगता है कि कोई उपयोगकर्ता किसी प्रॉपर्टी या एट्रिब्यूट के साथ इंटरैक्ट करेगा और तो उन्हें सिखाना बोझ नहीं है, तो फिर ऐसा करें.
उदाहरण <howto-checkbox> एलिमेंट. इसके बारे में यहां और समझाया गया है फिर से शामिल होने से जुड़ी समस्याओं से बचें.

बेहतर डेटा (ऑब्जेक्ट, अरे) को प्रॉपर्टी के तौर पर स्वीकार करने की कोशिश करें.

क्यों? आम तौर पर, बिल्ट-इन एचटीएमएल एलिमेंट के ऐसे कोई उदाहरण नहीं हैं जो इसके ज़रिए समृद्ध डेटा (सादे JavaScript ऑब्जेक्ट और सरणियों) एट्रिब्यूट. इसके बजाय, रिच डेटा को तरीका कॉल या प्रॉपर्टी. रिच डेटा को स्वीकार करने के कुछ नुकसान हैं. जैसे, एट्रिब्यूट: बड़े ऑब्जेक्ट को किसी स्ट्रिंग में क्रम से लगाना महंगा हो सकता है और इस स्ट्रिंगिफ़िकेशन प्रक्रिया में सभी ऑब्जेक्ट संदर्भ खो जाएंगे. इसके लिए उदाहरण के लिए, अगर किसी ऐसे ऑब्जेक्ट को स्ट्रिंगिफ़ाई किया जाता है जिसमें किसी दूसरे ऑब्जेक्ट का रेफ़रंस है, या शायद एक DOM नोड, वे संदर्भ खो जाएंगे.

एट्रिब्यूट में रिच डेटा प्रॉपर्टी न दिखाएं.

क्यों? एट्रिब्यूट के लिए रिच डेटा प्रॉपर्टी को दिखाने में बहुत ज़्यादा खर्चा नहीं करना पड़ता. एक ही JavaScript ऑब्जेक्ट को क्रम में लगाना और डीसीरियलाइज़ करना ज़रूरी है. जब तक तो आपके पास कोई ऐसा उदाहरण है जिसे सिर्फ़ इस सुविधा की मदद से ही हल किया जा सकता है. सबसे अच्छा है कि ऐसा न हो.

उन प्रॉपर्टी की जांच करें जो शायद एलिमेंट से पहले सेट की गई हों अपग्रेड किया गया.

क्यों? आपके एलिमेंट का इस्तेमाल करने वाला डेवलपर, एलिमेंट पर प्रॉपर्टी सेट करने की कोशिश कर सकता है लोड किए जाने से पहले. ऐसा खास तौर पर तब होता है, जब डेवलपर ऐसे फ़्रेमवर्क का इस्तेमाल कर रहा है जो कॉम्पोनेंट लोड करने और उन्हें स्टैंप करने का काम करता है पेज से लिंक कर सकते हैं और उनकी प्रॉपर्टी को मॉडल से बाइंड कर सकते हैं.
उदाहरण <howto-checkbox> एलिमेंट. यहां और विस्तार से बताया गया है प्रॉपर्टी को लेज़ी बनाएं.

क्लास खुद लागू न करें.

क्यों? जिन एलिमेंट को अपनी स्थिति बताने की ज़रूरत है उन्हें एट्रिब्यूट का इस्तेमाल करके ऐसा करना चाहिए. कॉन्टेंट बनाने आम तौर पर, class एट्रिब्यूट का मालिकाना हक अनजाने में आपके एलिमेंट का इस्तेमाल करने वाले और उसे खुद लिखे होने से डेवलपर क्लास पर स्टॉम्प करें.

इवेंट

अंदरूनी कॉम्पोनेंट की गतिविधि के जवाब में इवेंट डिस्पैच करता है.

क्यों? आपके कॉम्पोनेंट में ऐसी प्रॉपर्टी हो सकती हैं जो इसके बारे में सिर्फ़ आपका कॉम्पोनेंट जानता है. उदाहरण के लिए, टाइमर या ऐनिमेशन में पूरा हो जाता है या संसाधन पूरी तरह लोड हो जाता है. इवेंट की जानकारी भेजना मददगार होता है इन बदलावों के जवाब में, होस्ट को सूचित किया जाता है कि कॉम्पोनेंट की स्थिति अलग हैं.

जब होस्ट किसी प्रॉपर्टी को नीचे की ओर सेट कर रहा हो, तो ऐसे में इवेंट को डिस्पैच न करें डेटा फ़्लो) शामिल है.

क्यों? प्रॉपर्टी सेट करने वाले होस्ट के जवाब में, कोई इवेंट भेजना गैर-ज़रूरी है (होस्ट को मौजूदा स्थिति पता है, क्योंकि इसने अभी-अभी सेट किया है). डिस्पैच करने के इवेंट अगर होस्ट सेट की गई है, तो प्रॉपर्टी में डेटा के साथ अनंत लूप हो सकते हैं बाइंडिंग सिस्टम.
उदाहरण <howto-checkbox> एलिमेंट.

एक्सप्लेनर (ज़्यादा जानकारी देने वाले वीडियो)

पेज लेखक को ओवरराइड न करें

यह मुमकिन है कि आपके एलिमेंट का इस्तेमाल करने वाला डेवलपर, इनमें से कुछ चीज़ों को बदलना चाहे उसकी शुरुआती स्थिति. उदाहरण के लिए, उसके ARIA role या फ़ोकस करने की क्षमता को बदलकर, tabindex. देखें कि क्या ये और कोई दूसरे ग्लोबल एट्रिब्यूट सेट किए गए हैं, अपनी वैल्यू लागू करने से पहले.

connectedCallback() {
  if (!this.hasAttribute('role'))
    this.setAttribute('role', 'checkbox');
  if (!this.hasAttribute('tabindex'))
    this.setAttribute('tabindex', 0);

प्रॉपर्टी को लेज़ी बनाएं

डेवलपर आपके एलिमेंट पर प्रॉपर्टी सेट करने से पहले, परिभाषा लोड कर दी गई है. यह खास तौर पर तब सही होता है, जब डेवलपर फ़्रेमवर्क जो लोडिंग कॉम्पोनेंट, उन्हें पेज में इंसर्ट करता है, और बाइंडिंग करते हैं.

नीचे दिए गए उदाहरण में, Angular अपने मॉडल के isChecked प्रॉपर्टी को चेकबॉक्स की checked प्रॉपर्टी में बदलें. अगर कैसे-चेकबॉक्स लेज़ी लोड हुआ था, हो सकता है कि Angular सेट करने की कोशिश करे प्रॉपर्टी को अपग्रेड करने से पहले, उसे सही का निशान लगाकर चुना जा सकता है.

<howto-checkbox [checked]="defaults.isChecked"></howto-checkbox>

कस्टम एलिमेंट को इस स्थिति को हैंडल करना चाहिए. इसके लिए, यह जांचना ज़रूरी है कि किसी प्रॉपर्टी में पहले से ही इस इंस्टेंस पर सेट हो. <howto-checkbox> इस पैटर्न को दिखाने के लिए, _upgradeProperty() नाम वाले तरीके का इस्तेमाल किया जाता है.

connectedCallback() {
  ...
  this._upgradeProperty('checked');
}

_upgradeProperty(prop) {
  if (this.hasOwnProperty(prop)) {
    let value = this[prop];
    delete this[prop];
    this[prop] = value;
  }
}

_upgradeProperty(), अपग्रेड नहीं किए गए इंस्टेंस से वैल्यू को कैप्चर करता है और मिटा देता है प्रॉपर्टी शामिल की जाती है, ताकि वह कस्टम एलिमेंट के प्रॉपर्टी सेटर को शैडो न करे. इस तरह से, जब एलिमेंट की डेफ़िनिशन आखिर में लोड होती है, तो वह तुरंत सही स्थिति दिखाएं.

बार-बार होने वाली समस्याओं से बचना

अपने कारोबार की मौजूदा ज़रूरतों को पूरा करने के लिए, attributeChangedCallback() का इस्तेमाल प्रॉपर्टी का इस्तेमाल किया जा सकता है, उदाहरण के लिए:

// When the [checked] attribute changes, set the checked property to match.
attributeChangedCallback(name, oldValue, newValue) {
  if (name === 'checked')
    this.checked = newValue;
}

हालांकि, अगर प्रॉपर्टी सेटर एट्रिब्यूट की वैल्यू सबमिट करें.

set checked(value) {
  const isChecked = Boolean(value);
  if (isChecked)
    // OOPS! This will cause an infinite loop because it triggers the
    // attributeChangedCallback() which then sets this property again.
    this.setAttribute('checked', '');
  else
    this.removeAttribute('checked');
}

एक विकल्प यह है कि प्रॉपर्टी सेटर को एट्रिब्यूट को दिखाने की अनुमति दी जाए और गैटर से विशेषता के आधार पर उसकी वैल्यू तय करने के लिए कहा जाता है.

set checked(value) {
  const isChecked = Boolean(value);
  if (isChecked)
    this.setAttribute('checked', '');
  else
    this.removeAttribute('checked');
}

get checked() {
  return this.hasAttribute('checked');
}

इस उदाहरण में, एट्रिब्यूट जोड़ने या हटाने से प्रॉपर्टी भी सेट हो जाएगी.

आखिर में, खराब असर को ठीक करने के लिए, attributeChangedCallback() का इस्तेमाल किया जा सकता है जैसे कि ARIA स्टेटस लागू करना.

attributeChangedCallback(name, oldValue, newValue) {
  const hasValue = newValue !== null;
  switch (name) {
    case 'checked':
      // Note the attributeChangedCallback is only handling the *side effects*
      // of setting the attribute.
      this.setAttribute('aria-checked', hasValue);
      break;
    ...
  }
}