परिचय
वेब कॉम्पोनेंट, आधुनिक स्टैंडर्ड का एक सेट है जो:
- विजेट बनाना संभव होता है
- ...जिनका भरोसेमंद तरीके से फिर से इस्तेमाल किया जा सकता है
- ...और अगर कॉम्पोनेंट का अगला वर्शन मौजूद होता है, तो इससे पेज ब्रेक नहीं होंगे आंतरिक कार्यान्वयन विवरण को बदलता है.
क्या इसका मतलब यह है कि आपको यह तय करना है कि एचटीएमएल/JavaScript का इस्तेमाल कब करना है और वेब कॉम्पोनेंट का इस्तेमाल कब करना चाहिए? नहीं! एचटीएमएल और JavaScript आपके लिए इंटरैक्टिव विज़ुअल प्रॉडक्ट. विजेट, इंटरैक्टिव विज़ुअल प्रॉडक्ट होते हैं. यह अपने HTML और JavaScript कौशल का लाभ उठाना चाहते हैं, जब विजेट बनाना. वेब कॉम्पोनेंट के स्टैंडर्ड, आपकी मदद करने के लिए डिज़ाइन किए गए हैं करते हैं.
हालांकि, एक बुनियादी समस्या है जिसकी वजह से विजेट का पूरा फ़ायदा नहीं मिलता एचटीएमएल और JavaScript का इस्तेमाल करना मुश्किल है: विजेट में मौजूद DOM ट्री इन्हें पेज के बाकी हिस्से से अलग किया जाता है. एनकैप्सुलेशन की यह कमी इसका मतलब है कि आपके दस्तावेज़ की स्टाइलशीट गलती से आपके दस्तावेज़ के कुछ हिस्सों पर लागू हो सकती है विजेट के अंदर; शायद आपका JavaScript गलती से कुछ हिस्सों में बदलाव कर दे विजेट के अंदर; आपके आईडी, विजेट में मौजूद आईडी से ओवरलैप हो सकते हैं; वगैरह.
वेब कॉम्पोनेंट के तीन हिस्से होते हैं:
शैडो DOM, DOM ट्री एनकैप्सुलेशन की समस्या को हल करता है. कॉन्टेंट बनाने वेब कॉम्पोनेंट के चार हिस्से एक साथ काम करने के लिए डिज़ाइन किए गए हैं. हालांकि, यह भी चुन सकता है कि वेब कॉम्पोनेंट के किन हिस्सों का इस्तेमाल किया जाए. यह ट्यूटोरियल में शैडो DOM को इस्तेमाल करने का तरीका बताया गया है.
हेलो, शैडो वर्ल्ड
शैडो डीओएम की मदद से, एलिमेंट को नए तरह के नोड से जोड़ा जा सकता है उन्हें. इस नए तरह के नोड को शैडो रूट कहा जाता है. जिस तत्व के साथ कोई शैडो रूट जुड़ा होता है उसे शैडो कहा जाता है होस्ट. शैडो होस्ट का कॉन्टेंट रेंडर नहीं किया गया है; की सामग्री तो शैडो रूट रेंडर किया जाता है.
उदाहरण के लिए, अगर आपके पास इस तरह का मार्कअप था:
<button>Hello, world!</button>
<script>
var host = document.querySelector('button');
var root = host.createShadowRoot();
root.textContent = 'こんにちは、影の世界!';
</script>
इसके बजाय
<button id="ex1a">Hello, world!</button>
<script>
function remove(selector) {
Array.prototype.forEach.call(
document.querySelectorAll(selector),
function (node) { node.parentNode.removeChild(node); });
}
if (!HTMLElement.prototype.createShadowRoot) {
remove('#ex1a');
document.write('<img src="SS1.png" alt="Screenshot of a button with \'Hello, world!\' on it.">');
}
</script>
तुम्हारा पेज ऐसा दिखता है
<button id="ex1b">Hello, world!</button>
<script>
(function () {
if (!HTMLElement.prototype.createShadowRoot) {
remove('#ex1b');
document.write('<img src="SS2.png" alt="Screenshot of a button with \'Hello, shadow world!\' in Japanese on it.">');
return;
}
var host = document.querySelector('#ex1b');
var root = host.createShadowRoot();
root.textContent = 'こんにちは、影の世界!';
})();
</script>
इतना ही नहीं, अगर पेज पर मौजूद JavaScript, बटन के बारे में सवाल पूछता है
textContent
का मतलब यह नहीं है
“以んちは,影イ世界!”, लेकिन “नमस्ते!” क्योंकि डीओएम सबट्री
शैडो रूट के नीचे एनकैप्सुलेट किया हुआ होता है.
कॉन्टेंट को प्रज़ेंटेशन से अलग करना
अब हम शैडो डीओएम का इस्तेमाल करेंगे, ताकि अलग-अलग तरह के कॉन्टेंट को के साथ अपनी स्क्रीन शेयर करें. मान लें कि हमारे पास यह नाम टैग है:
<style>
.ex2a.outer {
border: 2px solid brown;
border-radius: 1em;
background: red;
font-size: 20pt;
width: 12em;
height: 7em;
text-align: center;
}
.ex2a .boilerplate {
color: white;
font-family: sans-serif;
padding: 0.5em;
}
.ex2a .name {
color: black;
background: white;
font-family: "Marker Felt", cursive;
font-size: 45pt;
padding-top: 0.2em;
}
</style>
<div class="ex2a outer">
<div class="boilerplate">
Hi! My name is
</div>
<div class="name">
Bob
</div>
</div>
मार्कअप यहां दिया गया है. आपको आज यह जवाब देना होगा. इस काम नहीं किया शैडो DOM का इस्तेमाल करें:
<style>
.outer {
border: 2px solid brown;
border-radius: 1em;
background: red;
font-size: 20pt;
width: 12em;
height: 7em;
text-align: center;
}
.boilerplate {
color: white;
font-family: sans-serif;
padding: 0.5em;
}
.name {
color: black;
background: white;
font-family: "Marker Felt", cursive;
font-size: 45pt;
padding-top: 0.2em;
}
</style>
<div class="outer">
<div class="boilerplate">
Hi! My name is
</div>
<div class="name">
Bob
</div>
</div>
डीओएम ट्री में एनकैप्सुलेशन नहीं है, इसलिए नाम टैग दस्तावेज़ के सामने दिखाई देता है. अगर पेज पर दूसरी चीज़ें मौजूद हैं, तो स्टाइलिंग या स्क्रिप्टिंग के लिए गलती से एक ही क्लास नाम का उपयोग कर लेते हैं, तो हम बुरा समय आएगा.
हम बुरे समय से बच सकते हैं.
पहला चरण: प्रज़ेंटेशन की जानकारी छिपाएं
इसका मतलब है कि हम सिर्फ़ इस बात पर ध्यान देते हैं:
- यह एक नाम टैग है.
- उसका नाम “बॉब” है.
सबसे पहले, हम ऐसा मार्कअप लिखते हैं जो हमारी पसंद के सही मतलब से मिलता-जुलता है:
<div id="nameTag">Bob</div>
फिर हम प्रज़ेंटेशन के लिए इस्तेमाल की जाने वाली सभी स्टाइल और divs को
<template>
एलिमेंट:
<div id="nameTag">Bob</div>
<template id="nameTagTemplate">
<span class="unchanged"><style>
.outer {
border: 2px solid brown;
… same as above …
</style>
<div class="outer">
<div class="boilerplate">
Hi! My name is
</div>
<div class="name">
Bob
</div>
</div></span>
</template>
इस समय, सिर्फ़ ‘बॉब’ को ही रेंडर किया जाता है. क्योंकि हम
प्रज़ेंटेशन वाले डीओएम एलिमेंट को अंदर ले जाया गया
<template>
एलिमेंट हैं, उन्हें रेंडर नहीं किया गया है, लेकिन
उन्हें JavaScript से ऐक्सेस किया जा सकता है. अब हम ऐसा इसलिए करते हैं,
शैडो रूट को पॉप्युलेट करें:
<script>
var shadow = document.querySelector('#nameTag').createShadowRoot();
var template = document.querySelector('#nameTagTemplate');
var clone = document.importNode(template.content, true);
shadow.appendChild(clone);
अब जब हमने शैडो रूट सेट अप कर लिया है, तो नाम टैग रेंडर हो जाता है फिर से. अगर नाम टैग पर राइट क्लिक करके तो आपको समझ में आएगा कि वह मधुर, सिमैंटिक मार्कअप है:
<div id="nameTag">Bob</div>
इससे पता चलता है कि शैडो डीओएम का इस्तेमाल करके, हमने दस्तावेज़ से नाम टैग की प्रज़ेंटेशन जानकारी. कॉन्टेंट बनाने शैडो डीओएम में प्रज़ेंटेशन की जानकारी शामिल होती है.
दूसरा चरण: कॉन्टेंट को प्रज़ेंटेशन से अलग करना
हमारा नाम टैग अब पेज से प्रज़ेंटेशन की जानकारी छिपा देता है, लेकिन प्रज़ेंटेशन को कॉन्टेंट से अलग नहीं करता है, क्योंकि कॉन्टेंट (“बॉब”) पेज पर मौजूद होता है. यह वह नाम होता है जिसे रेंडर किया जाता है वह जगह है जिसे हमने शैडो रूट में कॉपी किया था. अगर हम आपको नाम टैग में बदलना होगा, और वे उस पर सिंक न होना.
एचटीएमएल एलिमेंट कंपोज़िशनल होते हैं — इनमें बटन को टेबल में रखा जा सकता है, उदाहरण के लिए. हमें यहां कंपोज़िशन की ज़रूरत है: नाम टैग लाल बैकग्राउंड की कंपोज़िशन, “नमस्ते!” टेक्स्ट और कॉन्टेंट जो नाम टैग पर है.
कॉम्पोनेंट लेखक, आप तय करते हैं कि कंपोज़िशन आपकी ऐसेट के साथ कैसे काम करता है
<content>
नाम के नए एलिमेंट का इस्तेमाल करके बनाया गया विजेट. यह
विजेट के प्रज़ेंटेशन में एक इंसर्शन पॉइंट बनाता है और
इंसर्शन पॉइंट चेरी की मदद से, शैडो होस्ट से मौजूदा कॉन्टेंट तक
उस समय.
अगर हम शैडो डीओएम में मार्कअप को इस तरह बदलते हैं:
<span class="unchanged"><template id="nameTagTemplate">
<style>
…
</style></span>
<div class="outer">
<div class="boilerplate">
Hi! My name is
</div>
<div class="name">
<content></content>
</div>
</div>
<span class="unchanged"></template></span>
जब नाम टैग रेंडर किया जाता है, तो शैडो होस्ट का कॉन्टेंट
उस स्पॉट में प्रोजेक्ट किया जाता है जहां <content>
एलीमेंट
दिखाई देता है.
अब दस्तावेज़ की बनावट आसान है, क्योंकि इसका नाम सिर्फ़ एक ही जगह पर — दस्तावेज़. अगर आपके पेज को कभी भी उपयोगकर्ता नाम लिखना होगा, आप बस यह लिखें:
document.querySelector('#nameTag').textContent = 'Shellie';
और बस इतना ही. नाम टैग की रेंडरिंग अपने-आप अपडेट हो जाती है
ब्राउज़र से, क्योंकि हम प्रोजेक्टिंग कर रहे हैं और
<content>
के साथ नाम टैग सही जगह पर रखें.
<div id="ex2b">
अब हमने कॉन्टेंट और प्रज़ेंटेशन को अलग-अलग कर दिया है. यह दस्तावेज़ में कॉन्टेंट मौजूद हो; प्रज़ेंटेशन शैडो DOM में है. समय आने पर ब्राउज़र अपने-आप उन्हें सिंक करके रखता है का इस्तेमाल करें.
चरण 3: मुनाफ़ा
कॉन्टेंट और प्रज़ेंटेशन को अलग-अलग करके, हम पब्लिशर के लिए
जो कॉन्टेंट में हेर-फेर करता है — नाम टैग वाले उदाहरण में,
कोड को सिर्फ़ उस आसान स्ट्रक्चर का इस्तेमाल करना होता है जिसमें
कई के बजाय एक <div>
.
अब अगर हम अपना प्रज़ेंटेशन बदलते हैं, तो हमें कोड!
उदाहरण के लिए, मान लें कि हम अपना नाम टैग स्थानीय भाषा में करना चाहते हैं. यह अब भी एक नाम है टैग है, ताकि दस्तावेज़ में मौजूद सिमैंटिक कॉन्टेंट में कोई बदलाव न हो:
<div id="nameTag">Bob</div>
शैडो रूट का सेटअप कोड पहले जैसा ही रहता है. जो कुछ इस तरह बनाया जाता है शैडो रूट में बदलाव:
<template id="nameTagTemplate">
<style>
.outer {
border: 2px solid pink;
border-radius: 1em;
background: url(sakura.jpg);
font-size: 20pt;
width: 12em;
height: 7em;
text-align: center;
font-family: sans-serif;
font-weight: bold;
}
.name {
font-size: 45pt;
font-weight: normal;
margin-top: 0.8em;
padding-top: 0.2em;
}
</style>
<div class="outer">
<div class="name">
<content></content>
</div>
と申します。
</div>
</template>
यह वेब पर मौजूदा स्थिति के मुकाबले एक बड़ा सुधार है, क्योंकि आपके नाम का अपडेट कोड, वेबसाइट की कॉम्पोनेंट की वैल्यू जोड़ी जाती है, जो आसान और एक जैसा है. आपका नाम अपडेट कोड के लिए यह जानने की ज़रूरत नहीं है कि रेंडरिंग. अगर हम रेंडर किए गए कॉन्टेंट का इस्तेमाल करते हैं, तो आपको उसका नाम दिखेगा दूसरी अंग्रेज़ी में (“नमस्ते! मेरा नाम है”), लेकिन पहले जापानी में था (“䔳ကす”) से पहले. यह अंतर अर्थ की दृष्टि से अर्थहीन है तो वह नाम अपडेट नहीं किया जा सकता. इसलिए नाम अपडेट कोड को उस विवरण के बारे में जानने की ज़रूरत नहीं है.
अतिरिक्त क्रेडिट: बेहतर प्रोजेक्शन
ऊपर दिए गए उदाहरण में, <content>
एलिमेंट
चेरी, शैडो होस्ट से सारा कॉन्टेंट चुनता है. इसका इस्तेमाल करके
select
एट्रिब्यूट की मदद से, यह कंट्रोल किया जा सकता है कि
में जोड़ा जाता है. एक से ज़्यादा कॉन्टेंट का इस्तेमाल भी किया जा सकता है
एलिमेंट.
उदाहरण के लिए, अगर आपके पास कोई ऐसा दस्तावेज़ है जिसमें यह जानकारी शामिल है:
<div id="nameTag">
<div class="first">Bob</div>
<div>B. Love</div>
<div class="email">bob@</div>
</div>
और एक शैडो रूट जो खास कॉन्टेंट को चुनने के लिए सीएसएस सिलेक्टर का इस्तेमाल करता है:
<div style="background: purple; padding: 1em;">
<div style="color: red;">
<content **select=".first"**></content>
</div>
<div style="color: yellow;">
<content **select="div"**></content>
</div>
<div style="color: blue;">
<content **select=".email">**</content>
</div>
</div>
<div class="email">
एलिमेंट, दोनों से मैच होता है
<content select="div">
और <content
select=".email">
एलिमेंट. बॉब का ईमेल कितनी बार भेजा गया
पता दिखाई देता है और किन रंगों में?
इसका जवाब है कि बॉब का ईमेल पता एक बार दिखता है और वह पीला होता है.
इसकी वजह यह है कि Shadow DOM पर हैक करने वाले लोगों को पता है कि
स्क्रीन पर असल में रेंडर होने वाली चीज़ों का ट्री बनाना
बहुत बड़ी पार्टी. कॉन्टेंट एलिमेंट वह न्योता है जिससे हमें
कॉन्टेंट को दस्तावेज़ से बैकस्टेज शैडो डीओएम रेंडरिंग में ट्रांसफ़र करना
पार्टी. ये न्योते क्रम के मुताबिक डिलीवर किए जाते हैं; जिसे
यह इस बात पर निर्भर करता है कि आपका अनुरोध किसे भेजा गया है (यानी,
select
एट्रिब्यूट.) कॉन्टेंट, एक बार
न्योता स्वीकार करता है, हमेशा न्योता स्वीकार करता है (कौन नहीं करेगा?!) और उसे बंद कर देगा
जाता है. अगर उसके बाद उस पते पर फिर से न्योता भेजा जाता है, तो
घर पर कोई भी नहीं है और यह आपकी पार्टी में नहीं आता.
ऊपर दिए गए उदाहरण में, <div class="email">
मैच करता है
div
सिलेक्टर और .email
, दोनों
सिलेक्टर, क्योंकि div
वाला कॉन्टेंट एलिमेंट
सिलेक्टर, दस्तावेज़ में पहले आता है,
<div class="email">
येलो पार्टी में गया है और
ब्लू पार्टी में शामिल होने के लिए कोई उपलब्ध नहीं है. (यह शायद
यह क्यों होता है कि यह इतना नीला है, हालाँकि दुखी लोगों का साथ होता है, इसलिए आपको
कभी पता नहीं.)
अगर किसी आइटम को किसी भी पार्टी में शामिल न होने का न्योता भेजा गया है, तो वह नहीं मिलेगा किया गया है. आखिर में “नमस्ते, दुनिया” टेक्स्ट का क्या हुआ पहला उदाहरण. यह तब फ़ायदेमंद होता है, जब आपको मूल रूप से अलग रेंडरिंग: सिमैंटिक मॉडल दस्तावेज़, यानी वह चीज़ है जिसे पेज में मौजूद स्क्रिप्ट से ऐक्सेस किया जा सकता है, लेकिन ताकि इसे रेंडरिंग के लिए इस्तेमाल किया जा सके. साथ ही, इसे किसी एक अलग JavaScript का इस्तेमाल करके शैडो DOM में रेंडरिंग मॉडल को चालू या बंद किया गया.
उदाहरण के लिए, एचटीएमएल में तारीख चुनने वाला टूल अच्छा होता है. अगर आप <input
type="date">
लिखते हैं, तो आपको एक साफ़ पॉप-अप कैलेंडर मिलता है. हालांकि, अगर आपको
उपयोगकर्ता को उनकी मिठाई के लिए तारीखें चुनने की सुविधा देना चाहते हों
द्वीप पर छुट्टी (आपको पता है... रेड वाइन से बने हैमक के साथ.) आपने लोगों तक पहुंचाया मुफ़्त में
अपने दस्तावेज़ को इस तरह सेट अप करें:
<div class="dateRangePicker">
<label for="start">Start:</label>
<input type="date" name="startDate" id="start">
<br>
<label for="end">End:</label>
<input type="date" name="endDate" id="end">
</div>
शैडो DOM बनाएं जो एक आकर्षक कैलेंडर बनाने के लिए टेबल का इस्तेमाल करता है इसमें तारीखों की सीमा वगैरह हाइलाइट होती है. जब उपयोगकर्ता क्लिक करता है कैलेंडर के दिनों में, कॉम्पोनेंट startDate और endDate इनपुट; जब उपयोगकर्ता फ़ॉर्म सबमिट करता है, तो उन इनपुट एलिमेंट से वैल्यू सबमिट की जाती हैं.
मैंने दस्तावेज़ में लेबल क्यों शामिल किए, अगर वे रेंडर किया गया? इसकी वजह यह है कि अगर कोई उपयोगकर्ता, ब्राउज़र पर फ़ॉर्म देखता है जो शैडो DOM पर काम नहीं करता. फ़ॉर्म अब भी इस्तेमाल किया जा सकता है. सुंदर. उपयोगकर्ता को कुछ ऐसा दिखता है:
<div class="dateRangePicker">
<label for="start">Start:</label>
<input type="date" name="startDate" id="start">
<br>
<label for="end">End:</label>
<input type="date" name="endDate" id="end">
</div>
आपने Shadow DOM 101 पास किया है
ये Shadow DOM की बुनियादी बातें हैं — आपने Shadow DOM 101 को पास किया है! आप शैडो DOM की मदद से बहुत कुछ किया जा सकता है. उदाहरण के लिए, आप एनकैप्सुलेशन या आर्किटेक्ट के लिए, एक शैडो होस्ट या नेस्ट किए गए शैडो मॉडल-प्रचालित व्यू (एमडीवी) और शैडो DOM का इस्तेमाल करके आपके पेज पर ला सकते हैं. और वेब कॉम्पोनेंट, शैडो डीओएम से कहीं ज़्यादा हैं.
इसके बारे में हम बाद की पोस्ट में बताएंगे.