Şablon, alan ve gölge

Web bileşenlerinin avantajı, tekrar kullanılabilir olmalarıdır: Bir kullanıcı arayüzü widget'ını bir kez oluşturup birden çok kez yeniden kullanabilirsiniz. Bu sırada web bileşenleri oluşturmak için JavaScript'e ihtiyacınız varsa, JavaScript kitaplığına ihtiyacınız yoktur. HTML ve ilişkili API'ler, ihtiyacınız olan her şeyi sağlar.

Web Bileşeni standardı üç bölümden oluşur: HTML şablonları, Özel Öğeler ve Gölge DOM. Bunlar bir arada da, sorunsuz şekilde entegre edilebilen, özelleştirilmiş, bağımsız (kapsüllenmiş) yeniden kullanılabilir öğeler oluşturmaya olanak sağlar. gibi, bunları mevcut uygulamalara dönüştürebilirsiniz.

Bu bölümde <star-rating> öğesini oluşturacağız. Bu öğe, kullanıcıların belirli bir puan vermeniz gerekir. Özel bir öğeyi adlandırırken tümünün küçük harf kullanılması önerilir. Ayrıca, Çünkü bu, normal ve özel öğelerin ayırt edilmesine yardımcı olur.

Şu özelliklere sahip bir şablon oluşturmak için <template> ve <slot> öğelerini, slot özelliğini ve JavaScript'i kullanmayı ele alacağız: kapsüllenmiş bir Gölge DOM. Ardından, tanımlanan öğeyi yeniden kullanıp metnin bir bölümünü özelleştirerek istediğiniz gibi kullanabilirsiniz. Ayrıca, özel öğenin içinde ve dışında CSS'nin nasıl kullanıldığına da kısaca değineceğiz.

<template> öğesi

<template> öğesi, klonlanacak ve JavaScript ile DOM'ye eklenecek HTML parçalarını bildirmek için kullanılır. Öğenin içeriği varsayılan olarak oluşturulmaz. Bunun yerine, JavaScript kullanılarak örneklenirler.

<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>

Bir <template> öğesinin içeriği ekrana yazılmadığından, <form> ve içeriği oluşturulmaz. Evet, bu Codepen boş ancak HTML sekmesini denetlediğinizde <template> işaretlemesini görürsünüz.

Bu örnekte <form>, DOM'deki bir <template> öğesinin alt öğesi değildir. Bunun yerine, <template> öğelerinin içeriği alt öğedir HTMLTemplateElement.content tarafından döndürülen DocumentFragment Görünür hale getirmek için, içerikleri almak ve bu içerikleri DOM'ye eklemek üzere JavaScript kullanılmalıdır.

Bu kısa JavaScript, bir özel öğe oluşturmadı. Bu örnekte, <template> öğesinin içeriği <body> bölümüne eklenmiştir. İçerik görünür ve stil sahibi DOM'nin bir parçası haline geldi.

DOM&#39;de gösterilen önceki codepen&#39;in ekran görüntüsü.

Yalnızca bir yıldızlı değerlendirme için bir şablon uygulamak üzere JavaScript'in gerekmesi, pek yararlı bir yöntem değildir, ancak özelleştirilebilir yıldız puanı widget'ı faydalıdır.

<slot> öğesi

Özelleştirilmiş her olayın açıklaması eklemek için bir alan ekliyoruz. HTML, bir <slot> sağlar öğesini bir <template> içinde yer tutucu olarak kullanır ve ad sağlanırsa "adlandırılmış alan" oluşturur. Adlandırılmış bir alan kullanılabilir bir web bileşenindeki içeriği özelleştirmek için kullanılır. <slot> öğesi, özel bir öğenin alt öğelerinin nerede olduğunu kontrol edebilmemiz için bir yöntem sağlar öğesi gölge ağacına eklenmelidir.

Şablonumuzda <legend> öğesini <slot> olarak değiştiririz:

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

Öğe, değeriname Adlandırılmış bir alanın adı. Özel öğe bir alan için eşleşme içermiyorsa <slot> içeriği oluşturulur. Bu nedenle, HTML'lerinde içerik olmadan yalnızca <star-rating></star-rating> bulunuyorsa oluşturulabilecek genel içeriğe sahip bir <legend> ekledik.

<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>

slot özelliği, kullanılan genel bir özelliktir. <template> içindeki <slot> içeriğini değiştirin. Özel öğemizde, alan özelliğine sahip öğe bir <legend>. Ancak böyle olması gerekmez. Şablonumuzda <slot name="star-rating-legend">, <anyElement slot="star-rating-legend"> ile değiştirilir. Burada <anyElement> herhangi bir öğe, hatta başka bir özel öğe olabilir.

Tanımsız öğeler

<template> kaynağımızda <rating> öğesi kullandık. Bu özel bir öğe değil. Aksine, bilinmeyen bir öğedir. Tarayıcılar bir öğeyi tanımadıklarında başarısız olmaz. Tanınmayan HTML öğeleri, tarayıcı tarafından anonim satır içi olarak ele alınır öğeleri için stil özellikleri sunar. <span> özelliğine benzer şekilde, <rating> ve <star-rating> öğelerine kullanıcı aracısı uygulanmaz emin olun.

<template> ve içeriklerin oluşturulmadığını unutmayın. <template>, şu içeriklerin bulunduğu bilinen bir öğedir: oluşturulmaz. <star-rating> öğesi henüz tanımlanmadı. Bir öğe tanımlanana kadar tarayıcı bu öğeyi görüntüler önceden tanımlanmış öğeler de kullanabilirsiniz. Tanınmayan <star-rating> şimdilik anonim bir satır içi öğe olarak ele alındığından içerik göstergeler ve üçüncü <star-rating> içindeki <p>, <span> içindeymiş gibi görüntüleniyor.

Bu tanınmayan öğeyi özel bir öğeye dönüştürecek şekilde öğemizi tanımlayalım.

Özel öğeler

Özel öğeleri tanımlamak için JavaScript gerekir. Tanımlandığında <star-rating> öğesinin içeriği bir gölge kökü, kendisiyle ilişkilendirdiğimiz şablonun tüm içeriğini içerir. Şablondaki <slot> öğeleri değiştirilir slot özellik değeri <slot> öğesinin ad değeriyle eşleşen, <star-rating> içindeki öğenin içeriğiyle ( bir tane var. Değilse şablonun alanlarının içeriği görüntülenir.

Özel öğede bulunan ve bir alanla (üçüncü <star-rating> kapsamımızdaki <p>Is this text visible?</p>) ilişkilendirilmemiş içerik, gölge kökü eklenir ve bu nedenle görüntülenmez.

star-rating adlı özel öğeyi tanımlıyoruz. HTMLElement uzatarak:

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));
    }
  });

Öğe tanımlandığına göre, tarayıcı bir <star-rating> öğesiyle her karşılaştığında şimdi tanımlandığı gibi oluşturulur öğesi, şablonumuz olan #star-rating-template öğesine göre yapılır. Tarayıcı, düğüme bir gölge DOM ağacı ekler. şablon içeriğinin bir klonunu bu gölge DOM'ye gönderebilirsiniz. attachShadow() öğeleri sınırlı olduğunu unutmayın.

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

Geliştirici araçlarına göz atarsanız <template> içindeki <form> değerinin, her özel öğenin gölge kökünün bir parçası olduğunu görürsünüz. Geliştirici araçlarındaki her özel öğede <template> içeriğinin bir klonu görünür ve tarayıcıda görünür ancak içeriği öğenin kendisi ekranda oluşturulmaz.

Her özel öğedeki klonlanan şablon içeriklerini gösteren Geliştirici Araçları ekran görüntüsü.

<template> örneğinde, şablon içeriğini doküman gövdesine, içeriği ise normal DOM'ye ekledik. customElements tanımında aynı appendChild(), ancak kopyalanan şablon içerikleri kapsüllenmiş gölge DOM'si.

Yıldızların nasıl şekilsiz radyo düğmelerine döndüğünü fark ettiniz mi? Standart DOM yerine bir gölge DOM'nin parçası olduğundan, Codepen'in CSS sekmesindeki stil geçerli değildir. Bu sekmenin CSS'si stillerin kapsamı gölge DOM'a değil, dokümana ayarlanır. Bu nedenle, stiller uygulanmaz. Kapsamlı bir örnek oluşturmamız gerekir. stillerini ayarlamamızı öneririz.

Gölge DOM

Gölge DOM, CSS stillerini her bir gölge ağacına kapsama alarak onları belgenin geri kalanından izole eder. Bu, harici CSS anlamına gelir bileşeniniz için geçerli değildir ve bileşen stillerinin, kasıtlı olarak onları yönlendirir.

İçeriği bir gölge DOM'ye eklediğimizden, bir <style> öğesi ekleyebiliriz. özel öğeye kapsüllenmiş CSS sağlar.

Kapsamı özel öğeye ayarladığınızda, stillerin belgenin geri kalanına sızdırılması konusunda endişelenmemize gerek yoktur. Google'da seçicilerin kesinliğini önemli ölçüde azaltabilir. Örneğin, özel öğede kullanılan tek giriş radyo düğmesi olduğundan düğmelerinde, seçici olarak input[type="radio"] yerine input kullanabiliriz.

 <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>

Web bileşenleri <template> içi işaretlemeyle kapsüllenirken CSS stilleri ise gölge DOM'ye ayarlanır ve gizlenir. oluşturulan alan içeriği, <anyElement slot="star-rating-legend"> ve bileşenlerin dışındaki bölümü (<star-rating>) kapsüllenmemiş.

Mevcut kapsamın dışında stil

Dokümana bir gölge DOM içinden stil vermek ve gölge DOM'un içeriğini genel stillere odaklanıyor. Gölge DOM'nin sona erdiği ve normal DOM'nin başladığı gölge sınırından geçiş yapılabilir. Ancak bu sınır, bilinçli bir şekilde düşünmelisiniz.

Gölge ağacı, gölge DOM'sinin içindeki DOM ağacıdır. Gölge kökü, gölge ağacının kök düğümüdür.

:host sözde sınıfı, gölge barındırma öğesi olan <star-rating> öğesini seçer. Gölge ana makinesi, gölge DOM'nin bağlı olduğu DOM düğümüdür. Ana makinenin yalnızca belirli sürümlerini hedeflemek için :host() işlevini kullanın. Bu işlem, yalnızca iletilen parametreyle (ör. sınıf veya özellik seçici) eşleşen gölge ana makine öğelerini seçer. Seçmek için genel CSS'de star-rating { /* styles */ } veya şablon stillerinde :host(:not(#nonExistantId)) kullanabilirsiniz. açısından spesifikiyette küresel CSS kazanır.

::slotted() sözde öğesi, gölge DOM sınırını aşıyor işlevini çağırabilirsiniz. Seçiciyle eşleşirse aralıklı bir öğe seçer. Örneğimizde ::slotted(legend), üç efsaneyle uyumludur.

Global kapsamda CSS'den bir gölge DOM'yi hedeflemek için şablonun düzenlenmesi gerekir. part özelliğini ekleyerek stilini belirlemek istediğiniz herhangi bir öğeye eklenebilir. Ardından ::part() sözde öğesini kullanın öğesini kullanın. Sözde öğe için bağlantı veya kaynak öğe: ana makine veya özel öğe adı; bu örnekte star-rating. Parametre, part özelliğinin değeridir.

Şablon işaretlememiz şu şekilde başladıysa:

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

<form> ve <fieldset> şu şekilde hedeflenebilir:

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

Parça adları sınıflara benzer şekilde işlev görür: Bir öğenin birden fazla boşlukla ayrılmış bölüm adı olabilir ve birden çok öğe aynı parça adına sahip olmalıdır.

Google'ın özel öğeler oluşturmak için harika bir kontrol listesi vardır. Ayrıca risk yönetimi hakkında bildirim temelli gölge DOM'leri hakkında bilgi edinin.

Öğrendiklerinizi sınayın

Şablon, alan ve gölge hakkındaki bilginizi test edin.

Varsayılan olarak gölge DOM'sinin dışındaki stiller, içindeki öğelerin stilini belirler.

Doğru.
Tekrar deneyin.
Yanlış.
Doğru!

Aşağıdaki yanıtlardan hangisi <template> öğesiyle ilgili doğru açıklamadır?

Sayfanızdaki herhangi bir içeriği görüntülemek için kullanılan genel öğe.
Tekrar deneyin.
Yer tutucu öğe.
Tekrar deneyin.
HTML parçalarını bildirmek için kullanılan ve varsayılan olarak oluşturulmayan öğe.
Doğru!