টেমপ্লেট, স্লট, এবং ছায়া

ওয়েব উপাদানগুলির সুবিধা হল তাদের পুনরায় ব্যবহারযোগ্যতা: আপনি একবার একটি UI উইজেট তৈরি করতে পারেন এবং এটি একাধিকবার পুনরায় ব্যবহার করতে পারেন। ওয়েব কম্পোনেন্ট তৈরি করার জন্য আপনার জাভাস্ক্রিপ্টের প্রয়োজন থাকলেও আপনার জাভাস্ক্রিপ্ট লাইব্রেরির প্রয়োজন নেই। এইচটিএমএল এবং সংশ্লিষ্ট এপিআই আপনার প্রয়োজনীয় সবকিছু প্রদান করে।

ওয়েব কম্পোনেন্ট স্ট্যান্ডার্ড তিনটি অংশ নিয়ে গঠিত —এইচটিএমএল টেমপ্লেট , কাস্টম এলিমেন্টস এবং শ্যাডো ডম । একত্রিত করে, তারা কাস্টমাইজড, স্বয়ংসম্পূর্ণ (এনক্যাপসুলেটেড), পুনঃব্যবহারযোগ্য উপাদানগুলি তৈরি করতে সক্ষম করে যা বিদ্যমান অ্যাপ্লিকেশনগুলিতে নির্বিঘ্নে একত্রিত করা যেতে পারে, যেমন আমরা ইতিমধ্যেই কভার করেছি অন্যান্য HTML উপাদানগুলির মতো৷

এই বিভাগে, আমরা <star-rating> উপাদান তৈরি করব, একটি ওয়েব উপাদান যা ব্যবহারকারীদের এক থেকে পাঁচ তারার স্কেলে একটি অভিজ্ঞতাকে রেট দিতে দেয়। একটি কাস্টম উপাদানের নামকরণের সময়, সমস্ত ছোট হাতের অক্ষর ব্যবহার করার পরামর্শ দেওয়া হয়। এছাড়াও, একটি ড্যাশ অন্তর্ভুক্ত করুন, কারণ এটি নিয়মিত এবং কাস্টম উপাদানগুলির মধ্যে পার্থক্য করতে সহায়তা করে।

আমরা <template> এবং <slot> উপাদান, slot অ্যাট্রিবিউট এবং জাভাস্ক্রিপ্ট ব্যবহার করে একটি এনক্যাপসুলেটেড শ্যাডো ডম সহ একটি টেমপ্লেট তৈরি করার বিষয়ে আলোচনা করব। আমরা তারপরে সংজ্ঞায়িত উপাদানটি পুনরায় ব্যবহার করব, পাঠ্যের একটি বিভাগকে কাস্টমাইজ করব, ঠিক যেমন আপনি কোনও উপাদান বা ওয়েব উপাদান করবেন। আমরা কাস্টম উপাদানের ভিতরে এবং বাইরে থেকে CSS ব্যবহার করার বিষয়েও সংক্ষিপ্ত আলোচনা করব।

<template> উপাদান

<template> উপাদানটি জাভাস্ক্রিপ্টের সাহায্যে এইচটিএমএল-এর টুকরোগুলিকে ক্লোন করে DOM-এ ঢোকানোর ঘোষণা করতে ব্যবহৃত হয়। উপাদানের বিষয়বস্তু ডিফল্টরূপে রেন্ডার করা হয় না। বরং, তারা জাভাস্ক্রিপ্ট ব্যবহার করে তাৎক্ষণিক হয়।

<template id="star-rating-template">
  <form>
    <fieldset>
      <legend>Rate your experience:</legend>
      <rating>
        <input type="radio" name="rating" value="1" aria-label="1 star" required />
        <input type="radio" name="rating" value="2" aria-label="2 stars" />
        <input type="radio" name="rating" value="3" aria-label="3 stars" />
        <input type="radio" name="rating" value="4" aria-label="4 stars" />
        <input type="radio" name="rating" value="5" aria-label="5 stars" />
      </rating>
    </fieldset>
    <button type="reset">Reset</button>
    <button type="submit">Submit</button>
  </form>
</template>

যেহেতু একটি <template> উপাদানের বিষয়বস্তু স্ক্রিনে লেখা হয় না, তাই <form> এবং এর বিষয়বস্তু রেন্ডার করা হয় না। হ্যাঁ, এই কোডপেনটি ফাঁকা, কিন্তু আপনি যদি HTML ট্যাবটি পরীক্ষা করেন, আপনি <template> মার্কআপ দেখতে পাবেন।

এই উদাহরণে, <form> DOM-এ <template> -এর সন্তান নয়। বরং, <template> উপাদানগুলির বিষয়বস্তু হল HTMLTemplateElement.content সম্পত্তি দ্বারা প্রত্যাবর্তিত একটি DocumentFragment এর সন্তান। দৃশ্যমান করার জন্য, জাভাস্ক্রিপ্ট ব্যবহার করা আবশ্যক বিষয়বস্তু দখল করতে এবং সেই বিষয়বস্তুগুলিকে DOM-এ যুক্ত করতে।

এই সংক্ষিপ্ত জাভাস্ক্রিপ্ট একটি কাস্টম উপাদান তৈরি করেনি। বরং, এই উদাহরণটি <template> -এর বিষয়বস্তু <body> -এ যুক্ত করেছে। বিষয়বস্তু দৃশ্যমান, শৈলীযোগ্য DOM-এর অংশ হয়ে উঠেছে।

DOM-এ দেখানো আগের কোডপেনের স্ক্রিনশট।

শুধুমাত্র একটি স্টার রেটিং এর জন্য একটি টেমপ্লেট বাস্তবায়নের জন্য JavaScript এর প্রয়োজন খুব দরকারী নয়, তবে বারবার ব্যবহৃত, কাস্টমাইজযোগ্য স্টার রেটিং উইজেটের জন্য একটি ওয়েব উপাদান তৈরি করা দরকারী।

<slot> উপাদান

আমরা প্রতি ঘটনা কিংবদন্তি কাস্টমাইজড অন্তর্ভুক্ত করার জন্য একটি স্লট অন্তর্ভুক্ত করি। HTML একটি <template> ভিতরে একটি স্থানধারক হিসাবে একটি <slot> উপাদান প্রদান করে যেটি, একটি নাম প্রদান করলে, একটি "নামযুক্ত স্লট" তৈরি করে। একটি নামযুক্ত স্লট একটি ওয়েব উপাদানের মধ্যে সামগ্রী কাস্টমাইজ করতে ব্যবহার করা যেতে পারে। <slot> উপাদানটি আমাদেরকে নিয়ন্ত্রণ করার একটি উপায় দেয় যেখানে একটি কাস্টম উপাদানের বাচ্চাদের ছায়া গাছের মধ্যে ঢোকানো উচিত।

আমাদের টেমপ্লেটে, আমরা <legend> কে <slot> এ পরিবর্তন করি:

<template id="star-rating-template">
  <form>
    <fieldset>
      <slot name="star-rating-legend">
        <legend>Rate your experience:</legend>
      </slot>

যদি উপাদানটির একটি স্লট বৈশিষ্ট্য থাকে যার মান একটি নামযুক্ত স্লটের নামের সাথে মেলে তবে name বৈশিষ্ট্যটি অন্যান্য উপাদানগুলিতে স্লট বরাদ্দ করতে ব্যবহৃত হয়। যদি কাস্টম উপাদানটির একটি স্লটের সাথে মিল না থাকে, তাহলে <slot> -এর বিষয়বস্তু রেন্ডার করা হবে। তাই আমরা জেনেরিক বিষয়বস্তুর সাথে একটি <legend> অন্তর্ভুক্ত করেছি যেটি রেন্ডার করা ঠিক আছে যদি কেউ তাদের HTML-এ কোন বিষয়বস্তু ছাড়াই <star-rating></star-rating> অন্তর্ভুক্ত করে।

<star-rating>
  <legend slot="star-rating-legend">Blendan Smooth</legend>
</star-rating>
<star-rating>
  <legend slot="star-rating-legend">Hoover Sukhdeep</legend>
</star-rating>
<star-rating>
  <legend slot="star-rating-legend">Toasty McToastface</legend>
  <p>Is this text visible?</p>
</star-rating>

স্লট অ্যাট্রিবিউট হল একটি গ্লোবাল অ্যাট্রিবিউট যা একটি <template> -এর মধ্যে <slot> এর বিষয়বস্তু প্রতিস্থাপন করতে ব্যবহৃত হয়। আমাদের কাস্টম এলিমেন্টে, স্লট অ্যাট্রিবিউট সহ উপাদানটি হল একটি <legend> । এটা হওয়ার দরকার নেই। আমাদের টেমপ্লেটে, <slot name="star-rating-legend"> <anyElement slot="star-rating-legend"> দিয়ে প্রতিস্থাপিত হবে, যেখানে <anyElement> যেকোনো উপাদান, এমনকি অন্য কাস্টম উপাদানও হতে পারে।

অনির্ধারিত উপাদান

আমাদের <template> এ আমরা একটি <rating> উপাদান ব্যবহার করেছি। এটি একটি কাস্টম উপাদান নয়. বরং, এটি একটি অজানা উপাদান. ব্রাউজারগুলি ব্যর্থ হয় না যখন তারা একটি উপাদান চিনতে পারে না। অচেনা HTML উপাদানগুলিকে ব্রাউজার বেনামী ইনলাইন উপাদান হিসাবে বিবেচনা করে যা CSS দিয়ে স্টাইল করা যেতে পারে। <span> এর মতো, <rating> এবং <star-rating> উপাদানগুলির কোন ব্যবহারকারী-এজেন্ট প্রয়োগ করা শৈলী বা শব্দার্থবিদ্যা নেই।

মনে রাখবেন যে <template> এবং বিষয়বস্তু রেন্ডার করা হয় না। <template> একটি পরিচিত উপাদান যাতে এমন সামগ্রী রয়েছে যা রেন্ডার করা যায় না। <star-rating> উপাদানটি এখনও সংজ্ঞায়িত করা হয়নি। যতক্ষণ না আমরা একটি উপাদানকে সংজ্ঞায়িত করি, ব্রাউজার এটিকে সমস্ত অচেনা উপাদানের মতো প্রদর্শন করে। আপাতত, অচেনা <star-rating> একটি বেনামী ইনলাইন উপাদান হিসাবে বিবেচিত হয়, তাই কিংবদন্তি সহ বিষয়বস্তু এবং তৃতীয় <star-rating> -এ <p> যদি তারা <span> এ থাকত সেভাবে প্রদর্শিত হয়। পরিবর্তে

এই অচেনা উপাদানটিকে একটি কাস্টম উপাদানে রূপান্তর করতে আমাদের উপাদানটিকে সংজ্ঞায়িত করা যাক।

কাস্টম উপাদান

কাস্টম উপাদান সংজ্ঞায়িত করতে JavaScript প্রয়োজন। যখন সংজ্ঞায়িত করা হয়, তখন <star-rating> উপাদানটির বিষয়বস্তু একটি ছায়া রুট দ্বারা প্রতিস্থাপিত হবে যেখানে আমরা যে টেমপ্লেটটির সাথে যুক্ত করি তার সমস্ত বিষয়বস্তু রয়েছে। টেমপ্লেটের <slot> উপাদানগুলিকে <star-rating> -এর মধ্যে থাকা উপাদানের বিষয়বস্তু দিয়ে প্রতিস্থাপিত করা হয় যার slot বৈশিষ্ট্যের মান <slot> -এর নামের মানের সাথে মেলে, যদি একটি থাকে। যদি না হয়, টেমপ্লেটের স্লটের বিষয়বস্তু প্রদর্শিত হয়।

একটি কাস্টম উপাদানের মধ্যে বিষয়বস্তু যা একটি স্লটের সাথে যুক্ত নয়—আমাদের তৃতীয় <star-rating> -এ <p>Is this text visible?</p> - ছায়া রুটে অন্তর্ভুক্ত নয় এবং তাই প্রদর্শিত হয় না।

আমরা HTMLElement প্রসারিত করে star-rating নামের কাস্টম উপাদানটিকে সংজ্ঞায়িত করি :

customElements.define('star-rating',
  class extends HTMLElement {
    constructor() {
      super(); // Always call super first in constructor
      const starRating = document.getElementById('star-rating-template').content;
      const shadowRoot = this.attachShadow({
        mode: 'open'
      });
      shadowRoot.appendChild(starRating.cloneNode(true));
    }
  });

এখন যেহেতু উপাদানটি সংজ্ঞায়িত করা হয়েছে, যতবার ব্রাউজার একটি <star-rating> উপাদানের মুখোমুখি হবে, এটি #star-rating-template এর সাথে উপাদান দ্বারা সংজ্ঞায়িত হিসাবে রেন্ডার করা হবে, যা আমাদের টেমপ্লেট। ব্রাউজার নোডের সাথে একটি ছায়া DOM ট্রি সংযুক্ত করবে, সেই ছায়া DOM-এ টেমপ্লেট বিষয়বস্তুর একটি ক্লোন যুক্ত করবে। মনে রাখবেন যে উপাদানগুলির উপর আপনি attachShadow() করতে পারেন তা সীমিত

const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.appendChild(starRating.cloneNode(true));

আপনি যদি ডেভেলপার টুলগুলি দেখেন, তাহলে আপনি <template> থেকে <form> নোট করবেন প্রতিটি কাস্টম উপাদানের ছায়া রুটের অংশ। <template> বিষয়বস্তুর একটি ক্লোন ডেভেলপার টুলের প্রতিটি কাস্টম উপাদানে স্পষ্ট এবং ব্রাউজারে দৃশ্যমান, কিন্তু কাস্টম উপাদানের বিষয়বস্তু স্ক্রীনে রেন্ডার করা হয় না।

DevTools স্ক্রিনশট প্রতিটি কাস্টম উপাদানে ক্লোন করা টেমপ্লেট বিষয়বস্তু দেখাচ্ছে।

<template> উদাহরণে, আমরা নথির মূল অংশে টেমপ্লেট বিষয়বস্তু যুক্ত করেছি, নিয়মিত DOM-এ বিষয়বস্তু যুক্ত করেছি। customElements সংজ্ঞাতে , আমরা একই appendChild() ব্যবহার করেছি, কিন্তু ক্লোন করা টেমপ্লেট বিষয়বস্তু একটি encapsulated shadow DOM-এ যুক্ত করা হয়েছে।

লক্ষ্য করুন কিভাবে তারকারা স্টাইলবিহীন রেডিও বোতামে ফিরে গেছে? আদর্শ DOM-এর পরিবর্তে ছায়া DOM-এর অংশ হওয়ায়, Codepen-এর CSS ট্যাবের মধ্যে স্টাইলিং প্রযোজ্য নয়। সেই ট্যাবের CSS শৈলীগুলি ডকুমেন্টে স্কোপ করা হয়, ছায়া DOM-এ নয়, তাই শৈলীগুলি প্রয়োগ করা হয় না। আমাদের এনক্যাপসুলেটেড শ্যাডো ডম বিষয়বস্তু স্টাইল করার জন্য আমাদের এনক্যাপসুলেটেড শৈলী তৈরি করতে হবে।

ছায়া DOM

Shadow DOM প্রতিটি ছায়া গাছে CSS শৈলী স্কোপ করে, এটিকে নথির বাকি অংশ থেকে বিচ্ছিন্ন করে। এর মানে হল বাহ্যিক CSS আপনার কম্পোনেন্টে প্রযোজ্য নয়, এবং কম্পোনেন্ট শৈলীর বাকি ডকুমেন্টের উপর কোন প্রভাব নেই, যদি না আমরা ইচ্ছাকৃতভাবে তাদের নির্দেশ করি।

যেহেতু আমরা একটি ছায়া DOM-এ বিষয়বস্তু যুক্ত করেছি, তাই আমরা একটি <style> উপাদান অন্তর্ভুক্ত করতে পারি যা কাস্টম উপাদানটিতে এনক্যাপসুলেটেড CSS প্রদান করে।

কাস্টম উপাদানের জন্য স্কোপ করা হচ্ছে, আমাদের ডকুমেন্টের বাকি অংশে শৈলী বের হওয়ার বিষয়ে চিন্তা করতে হবে না। আমরা নির্বাচকদের নির্দিষ্টতা উল্লেখযোগ্যভাবে কমাতে পারি। উদাহরণস্বরূপ, যেহেতু কাস্টম উপাদানে ব্যবহৃত একমাত্র ইনপুটগুলি হল রেডিও বোতাম, তাই আমরা একটি নির্বাচক হিসাবে input[type="radio"] এর পরিবর্তে input ব্যবহার করতে পারি।

 <template id="star-rating-template">
  <style>
    rating {
      display: inline-flex;
    }
    input {
      appearance: none;
      margin: 0;
      box-shadow: none;
    }
    input::after {
      content: '\2605'; /* solid star */
      font-size: 32px;
    }
    rating:hover input:invalid::after,
    rating:focus-within input:invalid::after {
      color: #888;
    }
    input:invalid::after,
      rating:hover input:hover ~ input:invalid::after,
      input:focus ~ input:invalid::after  {
      color: #ddd;
    }
    input:valid {
      color: orange;
    }
    input:checked ~ input:not(:checked)::after {
      color: #ccc;
      content: '\2606'; /* hollow star */
    }
  </style>
  <form>
    <fieldset>
      <slot name="star-rating-legend">
        <legend>Rate your experience:</legend>
      </slot>
      <rating>
        <input type="radio" name="rating" value="1" aria-label="1 star" required/>
        <input type="radio" name="rating" value="2" aria-label="2 stars"/>
        <input type="radio" name="rating" value="3" aria-label="3 stars"/>
        <input type="radio" name="rating" value="4" aria-label="4 stars"/>
        <input type="radio" name="rating" value="5" aria-label="5 stars"/>
      </rating>
    </fieldset>
    <button type="reset">Reset</button>
    <button type="submit">Submit</button>
  </form>
</template>

যদিও ওয়েব উপাদানগুলি ইন- <template> মার্কআপ এবং CSS শৈলীগুলি ছায়া DOM-এ স্কোপ করা হয় এবং উপাদানগুলির বাইরের সমস্ত কিছু থেকে লুকানো থাকে, স্লট সামগ্রী যা রেন্ডার করা হয়, <anyElement slot="star-rating-legend"> <star-rating> এর অংশ , এনক্যাপসুলেটেড নয়।

বর্তমান সুযোগের বাইরে স্টাইল করা

ছায়া DOM-এর মধ্যে থেকে নথিকে স্টাইল করা এবং গ্লোবাল স্টাইল থেকে ছায়া DOM-এর বিষয়বস্তু স্টাইল করা সম্ভব, কিন্তু সহজ নয়। ছায়া সীমানা, যেখানে ছায়া DOM শেষ হয় এবং নিয়মিত DOM শুরু হয়, অতিক্রম করা যেতে পারে, তবে শুধুমাত্র খুব ইচ্ছাকৃতভাবে।

ছায়া গাছ হল ছায়া DOM এর ভিতরের DOM গাছ। ছায়ামূল হল ছায়া গাছের মূল নোড।

:host pseudo-class <star-rating> , ছায়া হোস্ট উপাদান নির্বাচন করে। ছায়া হোস্ট হল DOM নোড যার সাথে ছায়া DOM সংযুক্ত থাকে। হোস্টের শুধুমাত্র নির্দিষ্ট সংস্করণগুলিকে লক্ষ্য করতে, :host() ব্যবহার করুন। এটি শুধুমাত্র শ্যাডো হোস্ট উপাদান নির্বাচন করবে যা পাস করা প্যারামিটারের সাথে মেলে, যেমন ক্লাস বা অ্যাট্রিবিউট নির্বাচক। সমস্ত কাস্টম উপাদান নির্বাচন করতে, আপনি গ্লোবাল CSS-এ star-rating { /* styles */ } ব্যবহার করতে পারেন, অথবা টেমপ্লেট শৈলীতে :host(:not(#nonExistantId)) ব্যবহার করতে পারেন। নির্দিষ্টতার পরিপ্রেক্ষিতে, গ্লোবাল সিএসএস জিতেছে।

::slotted() ছদ্ম-উপাদানটি ছায়া DOM-এর মধ্যে থেকে ছায়া DOM সীমানা অতিক্রম করে। এটি একটি স্লটেড উপাদান নির্বাচন করে যদি এটি নির্বাচকের সাথে মেলে। আমাদের উদাহরণে, ::slotted(legend) আমাদের তিনটি কিংবদন্তির সাথে মিলে যায়।

গ্লোবাল স্কোপে CSS থেকে একটি ছায়া DOM টার্গেট করতে, টেমপ্লেটটি সম্পাদনা করতে হবে। part বৈশিষ্ট্য আপনি স্টাইল করতে চান যে কোনো উপাদান যোগ করা যেতে পারে. তারপরে ::part() ছদ্ম-উপাদানটি ব্যবহার করুন একটি ছায়া গাছের মধ্যে উপাদানগুলির সাথে মেলে যা পাস করা প্যারামিটারের সাথে মেলে। ছদ্ম-উপাদানের জন্য নোঙ্গর বা উদ্ভব উপাদান হল হোস্ট, বা কাস্টম উপাদানের নাম, এই ক্ষেত্রে star-rating । প্যারামিটার হল part বৈশিষ্ট্যের মান।

যদি আমাদের টেমপ্লেট মার্কআপ এভাবে শুরু হয়:

<template id="star-rating-template">
  <form part="formPart">
    <fieldset part="fieldsetPart">

আমরা এর সাথে <form> এবং <fieldset> টার্গেট করতে পারি:

star-rating::part(formPart) { /* styles */ }
star-rating::part(fieldsetPart) { /* styles */ }

অংশের নামগুলি ক্লাসের অনুরূপভাবে কাজ করে: একটি উপাদানের একাধিক স্থান-বিচ্ছিন্ন অংশের নাম থাকতে পারে এবং একাধিক উপাদানের একই অংশের নাম থাকতে পারে।

কাস্টম উপাদান তৈরি করার জন্য Google এর একটি চমত্কার চেকলিস্ট রয়েছে৷ আপনি ঘোষণামূলক ছায়া DOM সম্পর্কেও জানতে চাইতে পারেন।

আপনার উপলব্ধি পরীক্ষা করুন

টেমপ্লেট, স্লট এবং ছায়া সম্পর্কে আপনার জ্ঞান পরীক্ষা করুন।

বাইরে থেকে ডিফল্ট শৈলীতে ছায়া DOM ভিতরের উপাদানগুলিকে স্টাইল করবে।

মিথ্যা।
সত্য।

কোন উত্তরটি <template> উপাদানের সঠিক বর্ণনা?

একটি স্থানধারক উপাদান।
আপনার পৃষ্ঠার যেকোনো বিষয়বস্তু প্রদর্শন করতে ব্যবহৃত একটি সাধারণ উপাদান।
HTML এর টুকরো ঘোষণা করতে ব্যবহৃত একটি উপাদান, যা ডিফল্টরূপে রেন্ডার করা হবে না।