कस्टम एलिमेंट के साथ काम करना

परिचय

वेब पर ज़्यादातर कॉन्टेंट एक जैसा दिखता है. इसका मतलब समझने के लिए, Gmail जैसे "आधुनिक" वेब ऐप्लिकेशन पर एक नज़र डालें:

Gmail

<div> सूप में कोई आधुनिक चीज़ नहीं है. इसके बावजूद, हम वेब ऐप्लिकेशन इसी तरह बनाते हैं. यह बहुत बुरा है. क्या हमें अपने प्लैटफ़ॉर्म से ज़्यादा की मांग नहीं करनी चाहिए?

सेक्सी मार्कअप. आइए, इसे एक नियम बनाते हैं

एचटीएमएल, दस्तावेज़ को व्यवस्थित करने के लिए एक बेहतरीन टूल है. हालांकि, इसमें सिर्फ़ वे एलिमेंट इस्तेमाल किए जा सकते हैं जिन्हें एचटीएमएल स्टैंडर्ड तय करता है.

अगर Gmail के लिए मार्कअप खराब नहीं था, तो क्या होगा? अगर यह खूबसूरत था, तो:

<hangout-module>
    <hangout-chat from="Paul, Addy">
    <hangout-discussion>
        <hangout-message from="Paul" profile="profile.png"
            profile="118075919496626375791" datetime="2013-07-17T12:02">
        <p>Feelin' this Web Components thing.
        <p>Heard of it?
        </hangout-message>
    </hangout-discussion>
    </hangout-chat>
    <hangout-chat>...</hangout-chat>
</hangout-module>

कितना अच्छा है! यह ऐप्लिकेशन भी पूरी तरह से सही है. यह काम का और समझने में आसान है. सबसे अच्छी बात यह है कि इसे मेंटेन किया जा सकता है. आने वाले समय में, मुझे/आपको यह पता चल जाएगा कि यह क्या करता है. इसके लिए, बस इसके डिक्लेरेटिव बैकबोन की जांच करनी होगी.

शुरू करना

कस्टम एलिमेंट की मदद से, वेब डेवलपर नए तरह के एचटीएमएल एलिमेंट तय कर सकते हैं. यह स्पेसिफ़िकेशन, वेब कॉम्पोनेंट के तहत आने वाले कई नए एपीआई प्राइमिटिव में से एक है. हालांकि, यह सबसे अहम है. कस्टम एलिमेंट की मदद से अनलॉक की गई सुविधाओं के बिना, वेब कॉम्पोनेंट का कोई मतलब नहीं है:

  1. नए एचटीएमएल/डीओएम एलिमेंट तय करना
  2. ऐसे एलिमेंट बनाना जो दूसरे एलिमेंट से जुड़े हों
  3. कस्टम फ़ंक्शन को एक टैग में लॉजिक के हिसाब से बंडल करना
  4. मौजूदा डीओएम एलिमेंट के एपीआई को एक्सटेंड करना

नए एलिमेंट रजिस्टर करना

कस्टम एलिमेंट बनाने के लिए, document.registerElement() का इस्तेमाल किया जाता है:

var XFoo = document.registerElement('x-foo');
document.body.appendChild(new XFoo());

document.registerElement() का पहला आर्ग्युमेंट, एलिमेंट का टैग नाम होता है. नाम में डैश (-) होना चाहिए. उदाहरण के लिए, <x-tags>, <my-element>, और <my-awesome-app> मान्य नाम हैं, जबकि <tabs> और <foo_bar> नहीं हैं. इस पाबंदी की मदद से, पार्सर को कस्टम एलिमेंट को सामान्य एलिमेंट से अलग करने में मदद मिलती है. साथ ही, यह एचटीएमएल में नए टैग जोड़ने पर, आगे के साथ काम करने की सुविधा भी देता है.

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

डिफ़ॉल्ट रूप से, कस्टम एलिमेंट HTMLElement से इनहेरिट होते हैं. इसलिए, पिछला उदाहरण इसकी तरह है:

var XFoo = document.registerElement('x-foo', {
    prototype: Object.create(HTMLElement.prototype)
});

document.registerElement('x-foo') को कॉल करने पर, ब्राउज़र को नए एलिमेंट के बारे में पता चलता है. साथ ही, एक कन्स्ट्रक्टर मिलता है, जिसका इस्तेमाल <x-foo> के इंस्टेंस बनाने के लिए किया जा सकता है. इसके अलावा, अगर आपको कन्स्ट्रक्टर का इस्तेमाल नहीं करना है, तो एलिमेंट को इंस्टैंशिएट करने की अन्य तकनीकों का इस्तेमाल किया जा सकता है.

एलिमेंट एक्सटेंड करना

कस्टम एलिमेंट की मदद से, मौजूदा (नेटिव) एचटीएमएल एलिमेंट के साथ-साथ अन्य कस्टम एलिमेंट भी जोड़े जा सकते हैं. किसी एलिमेंट को एक्सटेंड करने के लिए, आपको उस एलिमेंट का नाम registerElement() और prototype पास करना होगा जिससे इनहेरिट करना है.

नेटिव एलिमेंट एक्सटेंड करना

मान लें कि आपको Ordinary Joe <button> से खुशी नहीं है. आपको "मेगा बटन" बनाने के लिए, इसकी सुविधाओं को बेहतर बनाना है. <button> एलिमेंट को बड़ा करने के लिए, ऐसा नया एलिमेंट बनाएं जो HTMLButtonElement का prototype और एलिमेंट का नाम extends इनहेरिट करता हो. इस मामले में, "button":

var MegaButton = document.registerElement('mega-button', {
    prototype: Object.create(HTMLButtonElement.prototype),
    extends: 'button'
});

नेटिव एलिमेंट से इनहेरिट किए गए कस्टम एलिमेंट को टाइप एक्सटेंशन कस्टम एलिमेंट कहा जाता है. ये HTMLElement के खास वर्शन से इनहेरिट होते हैं, ताकि यह बताया जा सके कि "एलिमेंट X एक Y है".

उदाहरण:

<button is="mega-button">

कस्टम एलिमेंट को बड़ा करना

<x-foo> कस्टम एलिमेंट को एक्सटेंड करने वाला <x-foo-extended> एलिमेंट बनाने के लिए, बस उसका प्रोटोटाइप इनहेरिट करें और बताएं कि आपको किस टैग से इनहेरिट करना है:

var XFooProto = Object.create(HTMLElement.prototype);
...

var XFooExtended = document.registerElement('x-foo-extended', {
    prototype: XFooProto,
    extends: 'x-foo'
});

एलिमेंट के प्रोटोटाइप बनाने के बारे में ज़्यादा जानने के लिए, नीचे JS प्रॉपर्टी और तरीके जोड़ना देखें.

एलिमेंट को अपग्रेड करने का तरीका

क्या आपने कभी सोचा है कि एचटीएमएल पार्सर, स्टैंडर्ड टैग के बजाय दूसरे टैग पर क्यों काम नहीं करता? उदाहरण के लिए, अगर हम पेज पर <randomtag> का एलान करते हैं, तो यह पूरी तरह से सही है. एचटीएमएल निर्देश के मुताबिक:

माफ़ करें <randomtag>! आपका ऐप्लिकेशन स्टैंडर्ड नहीं है और आपको HTMLUnknownElement से इनहेरिट किया गया है.

हालांकि, कस्टम एलिमेंट के लिए ऐसा नहीं है. मान्य कस्टम एलिमेंट के नाम वाले एलिमेंट, HTMLElement से इनहेरिट होते हैं. इस बात की पुष्टि करने के लिए, कंसोल: Ctrl + Shift + J (या Mac पर Cmd + Opt + J) को चालू करें और यहां दी गई कोड लाइन चिपकाएं. इससे true दिखेगा:

// "tabs" is not a valid custom element name
document.createElement('tabs').__proto__ === HTMLUnknownElement.prototype

// "x-tabs" is a valid custom element name
document.createElement('x-tabs').__proto__ == HTMLElement.prototype

ऐसे एलिमेंट जिनकी समस्या हल नहीं हुई

कस्टम एलिमेंट, document.registerElement() का इस्तेमाल करके स्क्रिप्ट से रजिस्टर किए जाते हैं. इसलिए, ब्राउज़र से उनकी परिभाषा रजिस्टर होने से पहले, उन्हें रजिस्टर किया जा सकता है या बनाया जा सकता है. उदाहरण के लिए, आपके पास पेज पर <x-tabs> का एलान करने का विकल्प है, लेकिन document.registerElement('x-tabs') को बाद में भी शुरू किया जा सकता है.

एलिमेंट को उनकी परिभाषा में अपग्रेड करने से पहले, उन्हें समाधान नहीं किए गए एलिमेंट कहा जाता है. ये ऐसे एचटीएमएल एलिमेंट हैं जिनका नाम मान्य कस्टम एलिमेंट है, लेकिन उन्हें रजिस्टर नहीं किया गया है.

इस टेबल से आपको चीज़ों को व्यवस्थित रखने में मदद मिल सकती है:

नाम इनसे इनहेरिट किया गया उदाहरण
हल नहीं किया गया एलिमेंट HTMLElement <x-tabs>, <my-element>
अज्ञात एलिमेंट HTMLUnknownElement <tabs>, <foo_bar>

एलिमेंट इंस्टैंशिएट करना

एलिमेंट बनाने की सामान्य तकनीकें, अब भी कस्टम एलिमेंट पर लागू होती हैं. किसी भी स्टैंडर्ड एलिमेंट की तरह, इन्हें एचटीएमएल में एलान किया जा सकता है या JavaScript का इस्तेमाल करके डीओएम में बनाया जा सकता है.

कस्टम टैग इंस्टैंशिएट करना

इनके बारे में एलान करें:

<x-foo></x-foo>

JS में डीओएम बनाना:

var xFoo = document.createElement('x-foo');
xFoo.addEventListener('click', function(e) {
    alert('Thanks!');
});

new ऑपरेटर का इस्तेमाल करें:

var xFoo = new XFoo();
document.body.appendChild(xFoo);

एक्सटेंशन एलिमेंट को इंस्टैंशिएट करना

एक्सटेंशन-स्टाइल के कस्टम एलिमेंट को तुरंत लागू करना, कस्टम टैग के बहुत करीब है.

इनके बारे में एलान करें:

<!-- <button> "is a" mega button -->
<button is="mega-button">

JS में डीओएम बनाना:

var megaButton = document.createElement('button', 'mega-button');
// megaButton instanceof MegaButton === true

जैसा कि आप देख सकते हैं, अब document.createElement() का एक ओवरलोड किया गया वर्शन है, जो is="" एट्रिब्यूट को अपने दूसरे पैरामीटर के तौर पर लेता है.

new ऑपरेटर का इस्तेमाल करें:

var megaButton = new MegaButton();
document.body.appendChild(megaButton);

अब तक, हमने ब्राउज़र को किसी नए टैग के बारे में बताने के लिए, document.registerElement() का इस्तेमाल करने का तरीका जाना है…लेकिन इससे ज़्यादा कुछ नहीं होता. अब प्रॉपर्टी और तरीके जोड़ते हैं.

JS प्रॉपर्टी और तरीके जोड़ना

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

यहां पूरा उदाहरण दिया गया है:

var XFooProto = Object.create(HTMLElement.prototype);

// 1. Give x-foo a foo() method.
XFooProto.foo = function() {
    alert('foo() called');
};

// 2. Define a property read-only "bar".
Object.defineProperty(XFooProto, "bar", {value: 5});

// 3. Register x-foo's definition.
var XFoo = document.registerElement('x-foo', {prototype: XFooProto});

// 4. Instantiate an x-foo.
var xfoo = document.createElement('x-foo');

// 5. Add it to the page.
document.body.appendChild(xfoo);

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

var XFoo = document.registerElement('x-foo', {
  prototype: Object.create(HTMLElement.prototype, {
    bar: {
      get: function () {
        return 5;
      }
    },
    foo: {
      value: function () {
        alert('foo() called');
      }
    }
  })
});

पहले फ़ॉर्मैट में, ES5 Object.defineProperty का इस्तेमाल किया जा सकता है. दूसरे विकल्प में, get/set का इस्तेमाल किया जा सकता है.

लाइफ़साइकल कॉलबैक के तरीके

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

कॉलबैक का नाम जब कॉल किया जाता है
createdCallback ऐलिमेंट का एक इंस्टेंस बनाया जाता है
attachedCallback दस्तावेज़ में कोई इंस्टेंस डाला गया हो
detachedCallback दस्तावेज़ से कोई इंस्टेंस हटा दिया गया हो
attributeChangedCallback(attrName, oldVal, newVal) कोई एट्रिब्यूट जोड़ा गया, हटाया गया या अपडेट किया गया

उदाहरण: <x-foo> पर createdCallback() और attachedCallback() को परिभाषित करना:

var proto = Object.create(HTMLElement.prototype);

proto.createdCallback = function() {...};
proto.attachedCallback = function() {...};

var XFoo = document.registerElement('x-foo', {prototype: proto});

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

लाइफ़साइकल कॉलबैक का इस्तेमाल करने का एक और उदाहरण, एलिमेंट पर डिफ़ॉल्ट इवेंट लिसनर सेट अप करना है:

proto.createdCallback = function() {
  this.addEventListener('click', function(e) {
    alert('Thanks!');
  });
};

मार्कअप जोड़ना

हमने <x-foo> बनाया है और उसे JavaScript API दिया है, लेकिन यह खाली है! क्या हमें इसे रेंडर करने के लिए कुछ एचटीएमएल देना चाहिए?

यहां लाइफ़साइकल कॉलबैक काम आते हैं. खास तौर पर, हम किसी एलिमेंट को कुछ डिफ़ॉल्ट एचटीएमएल देने के लिए, createdCallback() का इस्तेमाल कर सकते हैं:

var XFooProto = Object.create(HTMLElement.prototype);

XFooProto.createdCallback = function() {
    this.innerHTML = "**I'm an x-foo-with-markup!**";
};

var XFoo = document.registerElement('x-foo-with-markup', {prototype: XFooProto});

इस टैग को इंस्टैंशिएट करने और DevTools में जांच करने पर (राइट क्लिक करके, 'एलिमेंट की जांच करें' चुनें), आपको यह दिखेगा:

▾<x-foo-with-markup>
  **I'm an x-foo-with-markup!**
</x-foo-with-markup>

शैडो डीओएम में इंटरनल एलिमेंट को शामिल करना

शैडो डीओएम, कॉन्टेंट को इकट्ठा करने के लिए एक बेहतरीन टूल है. कस्टम एलिमेंट के साथ इसका इस्तेमाल करें और देखें कि क्या होता है!

शैडो डीओएम की मदद से, पसंद के मुताबिक बनाए गए एलिमेंट को ये सुविधाएं मिलती हैं:

  1. इसकी मदद से, उपयोगकर्ताओं को बदलाव लागू करने की ज़्यादा जानकारी नहीं दी जाती.
  2. स्टाइल एनकैप्सुलेशन…बिना किसी शुल्क के.

शैडो डीओएम से एलिमेंट बनाना, ऐसा एलिमेंट बनाना है जो बुनियादी मार्कअप को रेंडर करता है. अंतर createdCallback() में है:

var XFooProto = Object.create(HTMLElement.prototype);

XFooProto.createdCallback = function() {
    // 1. Attach a shadow root on the element.
    var shadow = this.createShadowRoot();

    // 2. Fill it with markup goodness.
    shadow.innerHTML = "**I'm in the element's Shadow DOM!**";
};

var XFoo = document.registerElement('x-foo-shadowdom', {prototype: XFooProto});

एलिमेंट के .innerHTML को सेट करने के बजाय, मैंने <x-foo-shadowdom> के लिए एक'शैडो रूट' बनाया है और फिर उसे मार्कअप से भरा है. DevTools में "शैडो DOM दिखाएं" सेटिंग चालू करने पर, आपको एक ऐसा #shadow-root दिखेगा जिसे बड़ा किया जा सकता है:

▾<x-foo-shadowdom>
  ▾#shadow-root
    **I'm in the element's Shadow DOM!**
</x-foo-shadowdom>

यह शैडो रूट है!

टेंप्लेट से एलिमेंट बनाना

एचटीएमएल टेंप्लेट, एपीआई का एक और नया प्राइमिटिव है, जो कस्टम एलिमेंट के साथ बेहतर तरीके से काम करता है.

उदाहरण: <template> और शैडो डीओएम से बनाए गए एलिमेंट को रजिस्टर करना:

<template id="sdtemplate">
  <style>
    p { color: orange; }
  </style>
  <p>I'm in Shadow DOM. My markup was stamped from a <template&gt;.
</template>

<script>
  var proto = Object.create(HTMLElement.prototype, {
    createdCallback: {
      value: function() {
        var t = document.querySelector('#sdtemplate');
        var clone = document.importNode(t.content, true);
        this.createShadowRoot().appendChild(clone);
      }
    }
  });
  document.registerElement('x-foo-from-template', {prototype: proto});
</script>

<template id="sdtemplate">
  <style>:host p { color: orange; }</style>
  <p>I'm in Shadow DOM. My markup was stamped from a <template&gt;.
</template>

<div class="demoarea">
  <x-foo-from-template></x-foo-from-template>
</div>

कोड की इन कुछ लाइनों में काफ़ी काम किया गया है. आइए, यह समझते हैं कि क्या-क्या हो रहा है:

  1. हमने एचटीएमएल में एक नया एलिमेंट रजिस्टर किया है: <x-foo-from-template>
  2. एलिमेंट का डीओएम, <template> से बनाया गया था
  3. शैडो डीओएम का इस्तेमाल करके, एलिमेंट की डरावनी जानकारी छिपाई जाती है
  4. शैडो डीओएम, एलिमेंट को स्टाइल का कवर देता है. उदाहरण के लिए, p {color: orange;} पूरे पेज को नारंगी रंग में नहीं बदल रहा है

बहुत बढ़िया!

कस्टम एलिमेंट की स्टाइल तय करना

किसी भी एचटीएमएल टैग की तरह, आपके कस्टम टैग के उपयोगकर्ता, सिलेक्टर की मदद से उसे स्टाइल कर सकते हैं:

<style>
  app-panel {
    display: flex;
  }
  [is="x-item"] {
    transition: opacity 400ms ease-in-out;
    opacity: 0.3;
    flex: 1;
    text-align: center;
    border-radius: 50%;
  }
  [is="x-item"]:hover {
    opacity: 1.0;
    background: rgb(255, 0, 255);
    color: white;
  }
  app-panel > [is="x-item"] {
    padding: 5px;
    list-style: none;
    margin: 0 7px;
  }
</style>

<app-panel>
    <li is="x-item">Do</li>
    <li is="x-item">Re</li>
    <li is="x-item">Mi</li>
</app-panel>

शैडो डीओएम का इस्तेमाल करने वाले एलिमेंट को स्टाइल करना

शैडो डीओएम को शामिल करने पर, यह बात बहुत ज़्यादा जटिल हो जाती है. शैडो डीओएम का इस्तेमाल करने वाले कस्टम एलिमेंट को इसके बेहतरीन फ़ायदे मिलते हैं.

शैडो डीओएम, किसी एलिमेंट में स्टाइल को शामिल करता है. शैडो रूट में तय की गई स्टाइल, होस्ट से बाहर नहीं निकलतीं और पेज से भी नहीं मिलतीं. कस्टम एलिमेंट के मामले में, एलिमेंट ही होस्ट होता है. स्टाइल को एन्कैप्सुलेट करने की प्रॉपर्टी की मदद से, कस्टम एलिमेंट भी अपने लिए डिफ़ॉल्ट स्टाइल तय कर सकते हैं.

शैडो डीओएम की स्टाइलिंग एक बहुत बड़ा विषय है! अगर आपको इस बारे में ज़्यादा जानकारी चाहिए, तो हमारा सुझाव है कि आप हमारे कुछ अन्य लेख पढ़ें:

:unresolved का इस्तेमाल करके, फ़्रीक्वेंटली ओवरक्वेरी होने से रोकना

एफ़ओयूसी को कम करने के लिए, कस्टम एलिमेंट में एक नई सीएसएस सूडो क्लास, :unresolved तय की गई है. इसका इस्तेमाल, समाधान नहीं किए गए एलिमेंट को टारगेट करने के लिए करें. ऐसा तब तक करें, जब तक ब्राउज़र आपके createdCallback() को ट्रिगर नहीं कर देता. लाइफ़साइकल के तरीके देखें. ऐसा होने के बाद, एलिमेंट को 'समस्या हल नहीं हुई' एलिमेंट नहीं माना जाता. अपग्रेड की प्रोसेस पूरी हो गई है और एलिमेंट अपनी परिभाषा में बदल गया है.

उदाहरण: रजिस्टर होने पर, "x-foo" टैग को फ़ेड इन करें:

<style>
  x-foo {
    opacity: 1;
    transition: opacity 300ms;
  }
  x-foo:unresolved {
    opacity: 0;
  }
</style>

ध्यान रखें कि :unresolved सिर्फ़ उन एलिमेंट पर लागू होता है जिन्हें ठीक नहीं किया गया है. यह HTMLUnknownElement से इनहेरिट किए गए एलिमेंट पर लागू नहीं होता. एलिमेंट को कैसे अपग्रेड किया जाता है देखें.

<style>
  /* apply a dashed border to all unresolved elements */
  :unresolved {
    border: 1px dashed red;
    display: inline-block;
  }
  /* x-panel's that are unresolved are red */
  x-panel:unresolved {
    color: red;
  }
  /* once the definition of x-panel is registered, it becomes green */
  x-panel {
    color: green;
    display: block;
    padding: 5px;
    display: block;
  }
</style>

<panel>
    I'm black because :unresolved doesn't apply to "panel".
    It's not a valid custom element name.
</panel>

<x-panel>I'm red because I match x-panel:unresolved.</x-panel>

इतिहास और ब्राउज़र के लिए सहायता

फ़ीचर का पता लगाना

सुविधा का पता लगाने का मतलब है कि document.registerElement() मौजूद है या नहीं, यह देखना:

function supportsCustomElements() {
    return 'registerElement' in document;
}

if (supportsCustomElements()) {
    // Good to go!
} else {
    // Use other libraries to create components.
}

ब्राउज़र समर्थन

document.registerElement() पहली बार Chrome 27 और Firefox ~23 में, फ़्लैग के पीछे दिखने लगा. हालांकि, तब से इस स्पेसिफ़िकेशन में काफ़ी बदलाव हुए हैं. Chrome 31, अपडेट किए गए स्पेसिफ़िकेशन के साथ काम करने वाला पहला वर्शन है.

जब तक ब्राउज़र के लिए बेहतर सहायता उपलब्ध नहीं हो जाती, तब तक polyfill का इस्तेमाल किया जाता है. इसका इस्तेमाल Google के Polymer और Mozilla के X-Tag में किया जाता है.

HTMLElementElement का क्या हुआ?

स्टैंडर्ड बनाने के काम में शामिल लोगों को पता है कि पहले <element> था. यह वाकई शानदार था. इसका इस्तेमाल करके, नए एलिमेंट को साफ़ तौर पर रजिस्टर किया जा सकता है:

<element name="my-element">
    ...
</element>

माफ़ करें, अपग्रेड की प्रोसेस, मुश्किल मामलों, और आर्मageddon जैसी स्थितियों में समय से जुड़ी बहुत सारी समस्याएं थीं. <element> को शेल्फ़ पर रखना पड़ा. अगस्त 2013 में, दिमित्री ग्लेज़कोव ने public-webapps पर पोस्ट करके बताया था कि कम से कम फ़िलहाल, इसे हटा दिया गया है.

ध्यान दें कि Polymer, <polymer-element> के साथ एलिमेंट रजिस्ट्रेशन का एलान करने वाला फ़ॉर्म लागू करता है. कैसे? इसमें document.registerElement('polymer-element') और टेंप्लेट से एलिमेंट बनाना लेख में बताई गई तकनीकों का इस्तेमाल किया गया है.

नतीजा

कस्टम एलिमेंट की मदद से, एचटीएमएल की शब्दावली को बढ़ाया जा सकता है, उसे नई तरकीबें सिखाई जा सकती हैं, और वेब प्लैटफ़ॉर्म के वर्महोल से कूदा जा सकता है. इन्हें शैडो डीओएम और <template> जैसे नए प्लैटफ़ॉर्म प्राइमिटिव के साथ जोड़ें, तो वेब कॉम्पोनेंट की तस्वीर साफ़ तौर पर दिखने लगती है. मार्कअप फिर से सेक्सी हो सकता है!

अगर आपको वेब कॉम्पोनेंट का इस्तेमाल करना है, तो हमारा सुझाव है कि आप Polymer देखें. इसमें आपको ज़रूरत के मुताबिक बहुत कुछ मिलेगा.