Ambil halaman web modern dan Anda akan melihat bahwa hal itu selalu
berisi konten yang dijahit bersama-sama dari berbagai sumber yang
berbeda; ini mungkin termasuk berbagi sosial widget dari Twitter atau
Facebook atau video Youtube bermain widget, mungkin melayani iklan hasil
personalisasi dari beberapa server iklan atau dapat mencakup beberapa
utilitas script atau style dari perpustakaan pihak ketiga host lebih di
CDN dan seterusnya. Dan jika semuanya HTML berbasis (seperti pilihan
hari ini) ada probabilitas tinggi tabrakan antara markup, script atau
style yang disajikan dari berbagai sumber. Umumnya, namespaces bekerja
untuk mencegah ini tabrakan yang memecahkan masalah sampai batas
tertentu, tetapi mereka tidak menawarkan enkapsulasi.
Enkapsulasi adalah salah satu pilar yang paradigma Object
Oriented Programming dan biasanya digunakan untuk membatasi internal
representasi dari object dari dunia luar.
Kembali ke masalah kami, kami pasti dapat merangkum kode JavaScript menggunakan closures atau menggunakan module pattern
tapi apa bisa kita lakukan semua ini untuk HTML markup? Bayangkan bahwa
kita harus membangun sebuah widget UI, apa bisa kita sembunyikan
rincian implementasi widget dari kode JavaScript dan CSS yang terdapat
pada halaman, yang mengkonsumsi widget kami? Selain itu, kami dapat
mencegah kode memakan dari mengacaukan widget kami fungsi atau tampilan
dan nuansa?
Shadow DOM datan untuk menyelamatkan
Satu-satunya solusi yang ada yang menciptakan batas antara kode Anda menulis dan kode yang mengkonsumsi, jelek - dan beroperasi dengan menggunakan iFrame
besar dan ketat, yang membawa dengan itu sendiri satu set masalah. Jadi
kita dipaksa untuk beradaptasi dengan pendekatan ini selalu?
Tidak
lagi! Shadow DOM memberikan kita cara yang elegan untuk tampilan
subtree DOM normal dengan dokumen khusus yang berisi lain subtree node,
yang ditembus skrip dan style. Bagian yang menarik adalah bahwa itu
bukanlah sesuatu yang baru! Berbagai browser telah menggunakan
metodologi ini untuk menerapkan widget native seperti tanggal, Slider, audio, video player, dll.
Mengaktifkan Shadow DOM
Pada
saat ini ditulis, versi saat ini dari Chrome (v29) mendukung inspecting
Shadpw DOM menggunakan Chrome DevTools. Buka Devtools dan klik pada cog
tombol di kanan bawah layar untuk membuka Settings panel, scroll ke bawah sedikit dan Anda akan melihat sebuah checkbox untuk menampilkan Shadow DOM.
Sekarang bahwa kita mengaktifkan browser kami, mari kita periksa internal pemutar audio default. Ketikkan:
Ke markup HTML Anda. Itu menunjukkan pemutar audio native berikut dalam browser yang didukung: Sekarang pergi ke depan dan memeriksa widget pemutar audio yang baru Anda buat.
Wow!
Ini menunjukkan representasi internal pemutar audio, yang dimana
tersembunyi. Seperti yang kita lihat, elemen audio menggunakan document fragment untuk mengadakan internal isi widget dan menambahkan untuk wadah elemen (yang dikenal sebagai Sahdow Host).
Advertisement
Shadow Host & Shadow Root
Shadow Host: adalah elemen DOM yang menjadi host subtree Shadow DOM atau DOM node yang berisi Shadow Root.
Shadow Root:
root DOM subtree mengandung Shadow DOM node. Ini adalah sebuah node
yang khusus, yang menciptakan batas antara normal DOM node dan shadow
DOM node. Ini adalah batas ini, yang mengenkapsulasi Shadow DOM node
dari setiap JavaScript atau CSS kode pada halaman cosuming.
Shadow DOM:
memungkinkan untuk beberapa DOM subtrees akan terdiri ke satu tree yang
lebih besar. Berikut gambar dari rancangan kerja W3C terbaik
menjelaskan konsep overlaying node. Ini adalah bagaimana tampilannya
sebelum Shadoww Root konten disertakan elemen Shadow Host:
Ketika dirender, Shadow tree berlangsung Shadow Host konten.
Proses overlaying node sering disebut sebagai komposisi.
Shadow Boundary:
dilambangkan dengan garis putus-putus pada gambar diatas. Ini
menandakan pemisahan antara dunia DOM normal dan Shadow DOM dunia.
Script dari kedua sisi tidak dapat menyeberangi batas ini dan
menciptakan kekacauan di sisi lain.
Halo Shadow DOM dunia
Cukup chit-chat saya
katakan, mari kita mendapatkan tangan kita kotor dengan menulis beberapa
kode. Misalkan kita memiliki markup berikut, yang menunjukkan pesan
pembuka yang sederhana.
1
<divid="welcomeMessage">Welcome to My World</div>
Tambahkan kode JavaScript berikut atau menggunakan Fiddle ini:
var shadowHost = document.querySelector("#welcomeMessage");
var shadowRoot = shadowHost.webkitCreateShadowRoot();
shadowRoot.textContent = "Hello Shadow DOM World";
Di sini kita membuat sebuah Shadow Root yang menggunakan webkitCreateShadowRoot() fungsi, pasangkan ke Shadow host dan kemudian hanya mengubah konten.
Perhatikan webkit
awalan khusus vendor sebelum nama fungsi. Hal ini menunjukkan bahwa
fungsi ini didukung pada beberapa browser yang hanya berbasis webkit.
Jika Anda pergi ke depan dan menjalankan contoh ini dalam browser yang didukung, maka Anda akan melihat "Hello Shadow DOM World" bukan "Selamat datang to My World" sebagai Shadow DOM node memiliki over-shadowed yang biasa. Penangkalan:
Seperti beberapa dari Anda mungkin memperhatikan, kami sedang mencampur
markup dengan script, yang umumnya tidak dianjurkan dan Shadow DOM
tidak terkecuali. Kami sengaja menghindari penggunaan template
begitu awal dalam permainan untuk menghindari kebingungan. Sebaliknya
Shadow DOM menyediakan solusi elegan untuk masalah ini dan kita akan
sampai di sana cukup segera.
Menghormati Shadow Boundary
Jika Anda mencoba dan mengakses konten yang merender tree menggunakan JavaScript, seperti:
var shadowHost = document.querySelector("#welcomeMessage");
var shadowRoot = shadowHost.webkitCreateShadowRoot();
shadowRoot.textContent = "Hello Shadow DOM World";
console.log(shadowHost.textContent);
// Prints "Welcome to My World" as the shadow DOM nodes are encapsulated and cannot be accessed by JavaScript
Anda
akan mendapatkan asli konten "Welcome to My World" dan bukan konten
yang sebenarnya dituliskan pada halaman, seperti Shadow DOM tree
yang dienkapsulasi dari script apapun. Ini juga berarti bahwa widget
yang Anda buat menggunakan Shaodow DOM aman dari setiap script yang
tidak diinginkan/bertentangan yang sudah ada di halaman.
Style enkapsulasi
Demikian
pula, semua CSS selector dilarang untuk menyeberangi shadow boundary.
Periksa kode berikut di mana kita telah diterapkan warna merah daftar
item, tetapi bahwa style hanya diterapkan ke node yang merupakan bagian
dari halaman parent, dan daftar item yang merupakan bagian dari Shadow
Root tidak terpengaruh dengan style ini.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<divclass="outer">
<divid="welcomeMessage">Welcome to My World</div>
<divclass="normalTree">Sample List
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
</div>
<style>
div.outer li {
color: red;
}
div.outer{
border: solid 1px; padding: 1em;
}
</style>
<scripttype="text/javascript">
var shadowHost = document.querySelector("#welcomeMessage");
var shadowRoot = shadowHost.webkitCreateShadowRoot();
Anda dapat melihat kode langsung di Fiddle. Enkapsulasi
ini berlaku bahkan jika kita membalikkan arah traversal. Setiap style
yang didefinisikan di dalam Shadow DOM tidak mempengaruhi dokumen parent
dan tetap scoped hanya ke Shadow Root. Periksa Fiddle
ini untuk contoh, dimana kita menerapkan warna biru untuk daftar item
dalam Shadow DOM tetapi dokumen parent daftar item tidak terpengaruh.
Namun
ada satu pengecualian di sini; Shadow DOM memberikan kita fleksibilitas
untuk style Shadow Host, DOM node yang memegang Shadlw DOM. idealnya
terletak di luar Shadow boundary dan bukan bagian dari Shadow Root,
tetapi menggunakan aturan @host, satu dapat menentukan
style yang dapat diterapkan ke Shadow Host seperti kita memiliki style
pesan pembuka dalam contoh di bawah ini.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<divid="welcomeMessage">Welcome to My World</div>
<scripttype="text/javascript">
var shadowHost = document.querySelector("#welcomeMessage");
var shadowRoot = shadowHost.webkitCreateShadowRoot();
shadowRoot.innerHTML = ["<style>",
"@host{ ",
"#welcomeMessage{ ",
"font-size: 28px;",
"font-family:cursive;",
"font-weight:bold;",
"}",
"}",
"</style>",
"<contentselect=''></content>"
].join(',').replace(/,/g,"");
</script>
Periksa Fiddle ini seperti kita style pesan pembuka Shadow Host menggunakan style yang didefinisikan dalam Shadow DOM.
Menciptakan Style Hook
Sebagai
pengembang widget, saya mungkin ingin pengguna widget saya mampu untuk
style elemen tertentu. Hal ini dicapai dengan memasukkan lubang ke
shadow boundary menggunakan kustom pseudo elemen.
Hal ini mirip dengan bagaimana beberapa browser membuat style hook
untuk pengembang untuk dstyle beberapa unsur-unsur internal widget
native. Misalnya, untuk style jempol dan jalur native slider Anda dapat
menggunakan ::- webkit-slider-thumb dan ::webkit-slider-runnable-track sebagai berikut:
Fork Fiddle ini dan menerapkan Style Anda sendiri untuk itu!
Event penargetan kembali
Jika suatu event yang berasal dari salah satu node dalam Shadow DOM melintasi Shadow Boundary kemudian kembali ditujukan untuk merujuk kepada Shadow Host untuk menjaga enkapsulasi. Pertimbangkan kode berikut:
01
02
03
04
05
06
07
08
09
10
11
12
13
<inputid="normalText"type="text"value="Normal DOM Text Node"/>
<divid="shadowHost"></div>
<inputid="shadowText"type="text"value="Shadow DOM Node"/>
<scripttype="text/javascript">
var shadowHost = document.querySelector('#shadowHost');
var shadowRoot = shadowHost.webkitCreateShadowRoot();
var template = document.querySelector('template');
Ini merender elemen-elemen dua input teks, satu melalui Normal DOM dan lain melalui Shadow DOM dan kemudian mendengarkan event click pada document.
Sekarang, ketika input teks kedua diklik, event ini berasal dari dalam
Shadow DOM dan ketika melintasi Shadow Boundary, event yang dimodifikasi
untuk mengubah elemen target ke Shaodw Host<div>elemen bukan<input>masukan teks. Kami juga telah memperkenalkan elemen <template> baru
di sini; ini secara konseptual mirip dengan sisi klien template solusi
seperti Handlerbars dan Underscores tetapi tidak seperti yang berkembang
dan tidak memiliki dukungan browser. Karena itu, menggunakan template
adalah cara ideal untuk menulis Shadow DOM daripada menggunakan tag
script seperti yang telah dilakukan sejauh seluruh artikel ini.
pemisahan kepentingan
Kita sudah tahu bahwa
itu adalah selalu ide yang baik untuk memisahkan konten sebenarnya dari
presentasi; Shadow DOM tidak harus menanamkan konten apapun, yang
akhirnya akan ditampilkan kepada pengguna. Sebaliknya, konten selalu
harus hadir pada halaman original dan tidak tersembunyi di dalam
template Shadow DOM. Ketika terjadi komposisi, konten ini harus kemudian
diproyeksikan ke titik penyisipan tepat didefinisikan dalam template
Shadow DOM. Mari kita menulis ulang contoh Hello World, menjaga dalam
pikiran di atas pemisahan - sebuah contoh live dapat ditemukan di Fiddle.
1
2
3
4
5
6
7
<divid="welcomeMessage">Welcome to Shadow DOM World</div>
<scripttype="text/javascript">
var shadowRoot = document.querySelector("#welcomeMessage").webkitCreateShadowRoot();
var template = document.querySelector("template");
shadowRoot.appendChild(template.content);
template.remove();
</script>
Ketika halaman dirender, isi dari Shadow Host diproyeksikan ke tempat dimana <content> elemen muncul. Ini adalah contoh yang sangat sederhana di mana <content>mengambil
segala sesuatu di dalam Shadow Host selama komposisi. Tapi itu sangat
baik bisa selektif dalam memilih konten dariShadow Host menggunakan
atribut select seperti yang ditunjukkan di bawah ini
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<divid="outer">How about some cool demo, eh ?
<divclass="cursiveButton">My Awesome Button</div>
</div>
<button>
Fallback Content
</button>
<style>
button{
font-family: cursive;
font-size: 24px;
color: red;
}
</style>
<scripttype="text/javascript">
var shadowRoot = document.querySelector("#outer").webkitCreateShadowRoot();
var template = document.querySelector("template");
Saya tidak akan babble banyak tentang aspek-aspek lain dari Web
komponen Spec dalam artikel ini, tetapi itu akan melakukan kita baik
untuk mengingat bahwa bersama-sama mereka memungkinkan kita untuk
membuat widget UI dapat digunakan kembali yang portabel di browser dalam
tampilan dan nuansa dan sepenuhnya dikemas dengan semua skrip d style
dari halaman yang dipakai.
No comments for "Intro untuk Shadow DOM"
Post a Comment