Gölge DOM 101

Dominic Cooney
Dominic Cooney

Giriş

Web Bileşenleri, aşağıdakileri sağlayan son teknoloji standartlardan oluşan bir settir:

  1. Widget oluşturma olanağı sunun
  2. ...ve güvenli bir şekilde yeniden kullanılabilir.
  3. ...ve bileşenin sonraki sürümü yayınlanırsa sayfaları kesintiye uğratmaz dahili uygulama ayrıntılarını değiştirir.

Bu, HTML/JavaScript'i ne zaman kullanacağınıza ve Web Bileşenleri ne zaman kullanılır? Hayır HTML ve JavaScript, görsel öğelerle entegredir. Widget'lar etkileşimli görsel öğelerdir. Google ve JavaScript becerilerinizden yararlanmanın yardımcı oluyorum. Web Bileşenleri standartları, bunu yapabilirsiniz.

Ancak widget'ların temel bir sorun (ör. widget'lar değil) HTML ve JavaScript'in kullanımı zor: Bir widget içindeki DOM ağacı sayfanın geri kalanından kapsüllenmiş olmalıdır. Enkapsülasyon eksikliği doküman stil sayfanızın, bazı bölümlerinde yanlışlıkla widget'ın içinde JavaScript'iniz, bazı durumlarda widget'ın içinde kimlikleriniz widget'ın içindeki kimliklerle çakışabilir; vb.

Web Bileşenleri üç bölümden oluşur:

  1. Şablonlar
  2. Gölge DOM
  3. Özel Öğeler

Gölge DOM, DOM ağacı kapsülleme sorununu ele alır. İlgili içeriği oluşturmak için kullanılan dört bölümü birlikte çalışmak üzere tasarlanmıştır, ancak Web Bileşenleri'nin hangi bölümlerinin kullanılacağını seçebilir. Bu eğiticisi, Gölge DOM'nin nasıl kullanılacağını gösterir.

Merhaba Gölge Dünya

Gölge DOM ile öğeler, ilişkili dosyalarla ilişkili yeni bir düğüm türü alabilir. gerekir. Bu yeni düğüm türü, gölge kökü olarak adlandırılır. Kendisiyle ilişkilendirilmiş bir gölge kökü olan öğeye gölge adı verilir ana makine. Gölge ana makinesinin içeriği oluşturulmaz; içerik bunun yerine gölge kökü oluşturulur.

Örneğin, şöyle bir işaretlemeniz varsa:

<button>Hello, world!</button>
<script>
var host = document.querySelector('button');
var root = host.createShadowRoot();
root.textContent = 'こんにちは、影の世界!';
</script>

CANNOT TRANSLATE

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

sayfanız

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

Bunun yanı sıra, sayfadaki JavaScript düğmenin textContent, almayacak "こんこちちこ\">影の世界!", ancak "Merhaba dünya!" çünkü DOM alt ağacı gölge kökü kapsüllenir.

İçeriği Sunudan Ayırma

Şimdi, içeriği web kampanyalarınızdan ayırmak için Gölge DOM'yi en iyi uygulamaları paylaşacağız. Şöyle bir ad etiketimiz olduğunu varsayalım:

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

İşaretlemeyi burada görebilirsiniz. Bugün yazacağınız metin budur. Hayır Gölge DOM kullanın:

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

DOM ağacında kapsülleme eksik olduğundan, ad etiketi belgede gösterilir. Sayfada başka öğeler varsa stil veya komut dosyası için aynı sınıf adlarını yanlışlıkla kullanırsanız, kötü zaman geçireceğiz.

Böylece kötü zamanlardan kaçınabiliriz.

1. Adım: Sunu Ayrıntılarını Gizleyin

Semantik olarak muhtemelen yalnızca şunlarla ilgileniyoruz:

  • Bu bir ad etiketidir.
  • Adı "Barış".

İlk olarak, istediğimiz gerçek anlamlara daha yakın bir işaretleme yazıyoruz:

<div id="nameTag">Bob</div>

Sonra, sunum için kullanılan tüm stilleri ve div'leri <template> öğesi:

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

Bu noktada "Bob" oluşturulan tek öğedir. Çünkü sunum DOM öğelerini içine taşıdı bir <template> öğesidir; oluşturulmazlar ancak Bunlara JavaScript'ten erişilebilir. Şimdi bunu gölge kökünü doldurun:

<script>
var shadow = document.querySelector('#nameTag').createShadowRoot();
var template = document.querySelector('#nameTagTemplate');
var clone = document.importNode(template.content, true);
shadow.appendChild(clone);

Artık bir gölge kökü oluşturduğumuza göre ad etiketi de tekrar. Ad etiketini sağ tıklayıp öğesi gibi görünür, anlamsal işaretlemeler

<div id="nameTag">Bob</div>

Bu, Gölge DOM kullanarak belgedeki ad etiketinin sunu ayrıntılarını içerir. İlgili içeriği oluşturmak için kullanılan sunu ayrıntıları Gölge DOM içine alınır.

2. Adım: İçeriği Sunudan Ayırın

Ad etiketimiz artık sayfadaki sunum ayrıntılarını gizler sunumu içerikten ayırmaz, içerik ("Bob" adı) sayfadadır, oluşturulan ad gölge köküne kopyaladığımızdır. Mevcut bir bu işlemi iki yerde yapmamız gerekirdi ve bunlar senkronize olun.

HTML öğeleri kompozisyondur; bir tablonun içine düğme koyabilir, örneğine bakalım. Burada kompozisyona ihtiyacımız var: Ad etiketi "Merhaba!" yazan kırmızı arka plan kompozisyonu metin ve içerik bir öğedir.

Bileşenin yazarı olarak, bestenin widget'ını <content> adlı yeni bir öğe ile değiştirin. Bu widget'ın sunumunda bir ekleme noktası oluşturur ve ekleme noktası, gölge ana makinesinden günümüze kadar gelen içerikleri seçer mesela.

Gölge DOM'deki işaretlemeyi şu şekilde değiştirirsek:

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

Ad etiketi oluşturulduğunda gölge ana makinesinin içeriği <content> öğesinin bulunduğu noktaya projeksiyon görünür.

Dokümanın yapısı daha basittir çünkü ad tek bir yerde: belge. Sayfanızın, kullanıcının adına bir şeyler yazmanız yeterlidir:

document.querySelector('#nameTag').textContent = 'Shellie';

Hepsi bu kadar. Ad etiketinin oluşturulması otomatik olarak güncellenir Çünkü web sitenizin içeriğini yansıttığımız için ad etiketini <content> ile yerleştirin.

<div id="ex2b">

Artık içerik ve sunumu ayırdık. dokümanda içerik var; emin olmanız gerekir. Zaman geldiğinde tarayıcı tarafından otomatik olarak senkronize edilirler bir şey oluşturmak için kullanılır.

3. Adım: Kâr

İçeriği ve sunumu ayırarak, süreci basitleştirmek için bir kod oluşturur. Ad etiketi örneğinde, kodunu yalnızca bir kod içeren basit bir yapıda birkaç yerine bir <div>.

Şimdi sunumumuzu değiştirirsek, standartlarımıza kod!

Örneğin, ad etiketimizi yerelleştirmek istediğinizi düşünelim. Hâlâ bir ad etiketinde belirtildiğinden, dokümanın anlamsal içeriği değişmez:

<div id="nameTag">Bob</div>

Gölge kök kurulum kodu aynı kalır. Önce gölge kökü değişiklikleri:

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

Bu, günümüzde web'deki duruma göre büyük bir gelişmedir çünkü ad güncelleme kodunuz, Ad Manager bileşen'i kullanabilirsiniz. Adınız güncelleme kodunun ne için kullanılan yapıyı bilmesine hakkında daha fazla bilgi edinin. Neyin oluşturulduğunu göz önünde bulundurursak ad, İngilizce ikinci sırada (“Hi! Benim adım”), ancak ilk adı Japonca ("く申まますnızdan önce"). Bu ayrım anlamsızdır gösteren adı güncelleme açısından bakıldığında Dolayısıyla ad güncelleme kodunun da bu ayrıntıdan haberdar olmasına gerek yoktur.

Ekstra Kredi: Gelişmiş Projeksiyon

Yukarıdaki örnekte <content> öğesi gölge ana makinesinden tüm içeriği alır. Şunu kullanarak: select özelliği varsa, bir öğe projesidir. Birden fazla içerik de kullanabilirsiniz öğeler.

Örneğin, şunu içeren bir dokümanınız varsa:

<div id="nameTag">
  <div class="first">Bob</div>
  <div>B. Love</div>
  <div class="email">bob@</div>
</div>

Belirli bir içeriği seçmek için CSS seçicileri kullanan bir gölge kökü:

<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"> öğesi, <content select="div"> ve <content select=".email"> öğeleri. İbrahim'in gönderdiği e-posta sayısı ve hangi renklerde görünür?

Yanıt, İbrahim'in e-posta adresinin bir kez görünmesi ve sarı olmasıdır.

Bunun nedeni, Gölge DOM'ye saldıranların bildiği gibi aslında ekranda gösterilenin ağacını oluşturmak, çok büyük bir partiydi. İçerik öğesi, bir araya gelerek dokümandan kulise giriş Gölge DOM oluşturmaya taraf. Bu davetiyeler sırayla teslim edilir: kime Davetiyenin kime gönderildiğine (yani, select özelliği için de kullanılmaktadır.) İçerik, bir kez davetleri her zaman kabul eder (kim etmez ki!) ve yapar gidilir. Bu adrese bir sonraki davetiye gönderilirse evde kimse olmadığını ve partinize gelmediğini unutmayın.

Yukarıdaki örnekte, <div class="email"> şununla eşleşir: hem div seçici hem de .email ancak div içeren içerik öğesi seçicinin dokümanın başlarında yer alır. <div class="email"> sarı partiye gider ve kimse partiye müsait değil. (Bu, neden bu kadar mavi. Hüzünlü insanı sever. asla bilmiyorum.)

Bir şeye hiçbir partiye davet edilmediğinde oluşmaz. "Hello, world" metnindeki ele alalım. Bu strateji, belirli bir hedefe oluşturmada büyük farklılıklar vardır: Anlamsal modeli Bu doküman, sayfadaki komut dosyaları tarafından erişilebilen, ancak gizlenecek kullanmak ve çok farklı bir cihaza bağlamak oluşturma modelini JavaScript kullanarak Gölge DOM'de oluşturun.

Örneğin, HTML'nin güzel bir tarih seçicisi vardır. <input type="date"> yazdığınızda düzenli bir pop-up takvim görürsünüz. Peki ya Kullanıcının tatlısı için bir tarih aralığı seçmesine izin vermek istiyor ada tatili (Red Vines'dan yapılmış hamaklarla.) Siz dokümanınızı şu şekilde ayarlayın:

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

ancak şık bir takvim oluşturmak için tablo kullanan Gölge DOM oluşturun Böylece, tarih aralığı vb. vurgulanır. Kullanıcı, takvimdeki günlerde, bileşen startDate ve endDate girişleri; Kullanıcı formu gönderdiğinde, bu giriş öğelerinden gelen değerler gönderilir.

Etiketlere eklememe neden olacaksa oluşturulmalı mı? Bunun nedeni, kullanıcı formu bir tarayıcıyla görüntülerse Form, Gölge DOM'yi desteklemez ancak güzel. Kullanıcı şuna benzer bir sayfa görür:

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

Gölge DOM 101'i Geçirsiniz

Gölge DOM'nin temelleri budur. Gölge DOM 101'i iletebilirsiniz. Şunları yapabilirsiniz: Shadow DOM ile daha fazlasını yapabilirsiniz. Örneğin, bir gölge ana makinesi, kapsülleme için iç içe yerleştirilmiş gölgeler veya mimar Model Tabanlı Görünümler (MDV) ve Gölge DOM'yi kullanarak sayfanızı. Ve Web Bileşenler Gölge DOM'dan daha fazlasıdır.

Bunları sonraki gönderilerde açıklayacağız.