Advertisement
  1. Web Design
  2. HTML5

HTML5 Penguasaan: Fragmen

Scroll to top
Read Time: 9 min
This post is part of a series called HTML5 Mastery Class.
HTML5 Mastery: Encoding
HTML5 Mastery: Tree Traversal

Indonesian (Bahasa Indonesia) translation by Puuma (you can also view the original English article)

HTML Mastery series imageHTML Mastery series imageHTML Mastery series image

Ada beberapa jenis DOM node. Ada Dokumen, Elemen, Teks dan banyak lagi, yang juga menerapkan Node umum. Salah satu yang lebih menarik, namun sampai sekarang tidak begitu sering digunakan yang, adalah DocumentFragment node. Itu pada dasarnya adalah wadah khusus untuk node.

Sebuah node DocumentFragment diperlakukan khusus dalam banyak DOM algoritma. Dalam artikel ini kita akan melihat beberapa metode API yang dirancang untuk digunakan dalam hubungannya dengan DocumentFragment. Kita juga akan melihat bahwa konsep node wadah penting untuk teknologi modern web lainnya, seperti <template> elemen atau bayangan seluruh DOM API. Tapi sebelum kita mulai kita harus memiliki sekilas fragmen parsing, yang tidak secara langsung berhubungan dengan DocumentFragment.

Fragmen Parsing

HTML5 parser dapat digunakan untuk lebih dari sekedar parsing dokumen lengkap. Dapat juga digunakan untuk parsing bagian dari sebuah dokumen, yang disebut fragmen. Menetapkan sifat seperti innerHTML atau outerHTML akan memicu fragmen parsing. Fragmen parsing karya-karya yang mirip parsing biasa dengan beberapa pengecualian. Perbedaan terbesar adalah kebutuhan untuk sebuah akar kontekstual.

Fragmen yang sedang parsing mungkin ditempatkan sebagai anak dari beberapa elemen, yang mungkin atau mungkin tidak memiliki nenek moyang tambahan. Informasi ini sangat penting untuk menentukan modus parsing saat ini, yang tergantung pada hirarki pohon saat ini. Selain itu, fragmen parsing tidak akan memicu eksekusi script karena alasan keamanan.

Oleh karenanya, kita dapat menggunakan kode seperti berikut, tapi kita tidak akan melihat hasil tambahan. Eksekusi script tidak dapat dipicu.

1
var foo = document.querySelector('#foo');
2
foo.innerHTML = '<b>Hallo World!</b><script>alert("Hi.");</script>';

Menggunakan fragmen parsing adalah cara sederhana untuk mengurangi operasi DOM. Agar tidak perlu membuat, mengubah dan menambahkan node, yang melibatkan konteks switch dan karenanya operasi DOM, kami bekerja secara eksklusif dalam membangun string, yang kemudian dievaluasi dan ditangani dari parser. Oleh karena itu kami hanya memiliki satu, atau hanya beberapa, operasi DOM. Kerugian dari metode ini adalah bahwa kita memerlukan parser, dan lainnya bekerja di JavaScript. Pertanyaan kuncinya adalah: Apakah lebih memakan waktu? Apakah DOM berbagai operasi lebih mahal daripada semua manipulasi string JavaScript diperlukan, atau apakah itu sebaliknya?

Jelas ini tergantung pada kasus. Untuk skenario tertentu, Grgur Grisogono melakukan pekerjaan untuk membandingkan performa menggunakan beberapa metode. Hal ini juga sangat tergantung pada browser, terutama seberapa cepat mesin JavaScript. Nilai yang lebih tinggi berarti lebih operasi dan oleh karena itu yang diinginkan.

innerHTML appendChild DocumentFragmentinnerHTML appendChild DocumentFragmentinnerHTML appendChild DocumentFragment

Meskipun browser cepat hari ini, perilaku relatif masih berlaku. Ini harus memotivasi kami untuk mencari solusi yang lebih baik dan mempelajari lebih lanjut tentang DocumentFragment.

Operasi DOM Aggregate

Ide di balik DocumentFragment node sederhana: sebuah wadah untuk objekNode. Ketika DocumentFragment ditambahkan, itu diperluas untuk menambahkan hanya isi kontainer, tidak wadah itu sendiri. Jika salinan dalam DocumentFragment diminta, isinya adalah kloning juga. Wadah itu sendiri akan pernah melekat node lain, meskipun harus memiliki pemilik, yang merupakan dokumen yang menciptakan fragmen.

Menciptakan DocumentFragment bekerja sebagai berikut:

1
var fragment = document.createDocumentFragment();

Dari titik ini, fragmen berperilaku persis seperti simpul induk DOM lainnya. Kami dapat melampirkan node, menghapus node atau mengakses node yang sudah ada. Tersedia pilihan untuk menjalankan query CSS menggunakan querySelector dan querySelectorAll. Paling penting, sebagaimana telah disebutkan, kita dapat mengkloning node menggunakan cloneNode().

Template HTML

Jika fragmen dokumen sangat bagus, mengapa tidak menggunakannya untuk templating?  Yah, DocumentFragment tidak bisa dibangun di HTML, seperti konsep hanya terpapar melalui DOM API. Itu karena itu hanya mungkin untuk membuat wadah di JavaScript. Hal ini mengurangi manfaat penggunaan banyak. Sekarang pendekatan yang paling populer masih berorientasi teks. Kita mulai dengan menempatkan template di pseudo<script> Elemen adalah palsu, karena atribut type akan ditetapkan untuk tipe-mime tidak valid.  Dengan cara ini tidak akan ada yang dieksekusi, tetapi konten teks dari elemen akan menggunakan aturan penguraian yang berbeda. 

Parsing ModesParsing ModesParsing Modes

Gambar di atas menunjukkan negara tokenization. Aturan parsing tag script istimewa, karena parsing akan terjadi dengan keadaan khusus tokenization. HTML tahu lima tokenization Serikat, tetapi yang kelima, Plaintext, sangat tidak menarik bagi kita. Negara Rawtext ini sangat mirip dengan Script, yang membuat kita dengan tiga negara untuk menjelaskan.

Mari kita pertimbangkan contoh. Kami menggunakan tiga elemen yang baik wakil untuk masing-masing dari tiga negara yang tersisa. The <div> elemen adalah, seperti banyak orang lain, dalam rezim parsing karakter (PCData). <textarea>, Menggunakan RCData seperti, misalnya,<title> elemen. Bahkan lebih seperti karakter mentah adalah bagian Rawtext, yang dapat diwakili oleh menggunakan <style> Ada perbedaan halus mengenai melarikan diri antara bagian Rawtext dan Script. Namun, kami akan memperlakukan mereka sebagai setara dalam pembahasan berikut.

1
var example = '<br>me & you > them';
2
var types = ["div", "textarea", "script"];
3
4
types.forEach(function (type) {
5
  var foo = document.createElement(type);
6
  foo.innerHTML = example;
7
  console.log(foo.innerHTML);
8
})

Mungkin kita jangkakan output yang sama, tetapi mengetahui bahwa ada perbedaan: siapa yang tahu seperti apa mereka akan terlihat.

1
<br>me &amp; you &gt; them
2
&lt;br&gt;me &amp; you &gt; them
3
<br>me & you > them

Terakhir cocokkan input string sempurna. Oleh karena itu kami memiliki pemenang yang sesungguhnya. Jadi ini menjelaskan mengapa elemen <script> begitu popular untuk mengangkut fragment templating. Tapi di sini adalah tempat bagian yang lucu dimulai. Kebanyakan mesin template akan membuat fungsi dari string, yang mengambil model dan meludah keluar Daftar dihasilkan DOM node untuk tampilan. Beberapa mungkin sudah mengikat nilai tergantung pada modelnya. Yang penting adalah generasi node, yang sebagian besar berorientasi pada string, setidaknya selama iterasi pertama.

W3C diakui situasi dan bereaksi dengan memperkenalkan <template> elemen. Elemen dapat dipahami sebagai pembawa DocumentFragment. Karena DocumentFragment tidak berpartisipasi langsung dalam DOM pohon, itu melekat pada sebuah node melalui properti. Menggunakan elemen semudah contoh berikut:

1
<template>
2
  <img src="{src}" alt="{alt}">
3
  <div class="comment">{comment}</div>
4
</template>

Dalam DOM, kita tidak akan melihat anak-anak setiap elemen ini. Semua anak telah terpasang pada contoh DocumentFragment unit, yang dapat diakses melalui properti konten.

Mari kita pahami:

1
var fragment = document.querySelector('template').content;
2
var img = fragment.querySelector('img');
3
var comments = fragment.querySelectorAll('.comment');

Teks telah dimasukkan ke dalam kurung kurawal untuk menunjukkan niat kita memperlakukan mereka sebagai pengganti. Ada tidak ada sistem mengisi mereka secara otomatis.

Mari kita membuat fungsi kembali node terkandung bagi kita. Kami menyesuaikan kode untuk contoh sebelumnya.

1
function createNodes (model) {
2
  var fragment = document.querySelector('template').content;
3
	var instance = fragment.clone(true);//deep cloning!

4
	var img = instance.querySelector('img');
5
	img.setAttribute('src', model.src);
6
	img.setAttribute('alt', model.alt);
7
	var div = instance.querySelector('div');
8
	div.textContent = model.comment;
9
	return instance;
10
}

Generalisasi dimungkinkan oleh iterasi atas semua atribut dan elemen node anak, mengganti teks yang cocok dengan struktur yang telah ditetapkan dalam atribut dan teks node. Akhirnya node terkandung dapat ditambahkan di suatu tempat:

1
var nodes = createNodes({ 
2
	src: 'image.png',
3
	alt: 'Image',
4
	comment: 'Great!'
5
});
6
document.querySelector('#comments').appendChild(nodes);

Ada tiga aspek penting <template> elemen:

  1. Memicu parsing mode yang berbeda. Ini adalah lebih dari hanya beberapa elemen.
  2. Anak-anak tidak akan dilampirkan untuk DOM, tetapi untuk DocumentFragment yang dapat diakses melalui konten.
  3. Kita harus membuat salinan dalam fragmen sebelum kita dapat menggunakannya.

Akhirnya, sebuah fragmen dokumen sangat berguna yang dapat bahkan dimanfaatkan untuk membuat bagian-bagian kecil situs web dapat digunakan kembali dan lebih fleksibel.

Bayangan DOM

Permintaan untuk komponen-komponen web telah meledak dalam beberapa tahun terakhir. Banyak kerangka kerja front-end mencoba untuk meniru jenis struktur komponen web. Itu diperlukan, bagaimanapun, memiliki DOM nyata yang mendukung, meskipun polyfills tentu saja mungkin. Proyek polimer adalah contoh yang baik dari polyfills besar, menampilkan apa yang bisa dilakukan dengan web komponen.

DOM bayangan memungkinkan kita untuk melakukan adalah untuk menambahkan DocumentFragment untuk setiap elemen. Ada tiga kendala:

  1. DocumentFragment telah menjadi istimewa-itu harus ShadowRoot.
  2. Setiap Elemen hanya dapat memiliki satu ShadowRoot, atau tidak tentu.
  3. Isi ShadowRoot dipisahkan dari asli DOM.

Kendala-kendala ini memiliki konsekuensi. 

Salah satu konsekuensi dari melampirkan ShadowRoot ke elemen adalah bahwa elemen tersebut tidak diberikan lagi — sebagai gantinya konten dalam bayangan DOM ditampilkan.   Kontennya mencakup, bagaimanapun, yang berarti bahwa itu mungkin mengikuti aturan styling sendiri.  Juga seluruh proses penanganan acara sedikit berbeda. 

Sebagai hasilnya, konsep baru lainnya telah diperkenalkan: slot.  Kita dapat mendefinisikan slot di DOM bayangan kami, yang diisi dengan node dari elemen, yang menyelenggarakan ShadowRoot. Tampaknya jelas bahwa menciptakan kustom elemen, yang membawa DOM bayangan, adalah ide yang baik. Spesifikasi elemen seluruh adat adalah reaksi untuk itu.

Jadi bagaimana kita bisa menggunakan DOM bayangan? Mari kita lakukan beberapa JavaScript untuk mengungkapkan API. Kita mulai dengan fragmen HTML berikut:

1
<div id="#shadow-dialog">
2
	<span slot="header">
3
		My header title
4
	</span>
5
	<div slot="content">
6
		<strong>Some very important content</strong>
7
	</div>
8
</div>

Pada titik ini semuanya berperilaku seperti biasa. Berikut adalah mana keterampilan JavaScript kita menuntut:

1
var context = document.querySelector('#shadow-dialog');
2
var root = context.attachShadow({ mode: 'open' });
3
var headerSlot = document.createElement('slot');
4
headerSlot.name = 'header';
5
root.appendChild(headerSlot);
6
var contentSlot = document.createElement('slot');
7
contentSlot.name = 'content';
8
root.appendChild(contentSlot);

Ke sini kita tidak mendapatkan banyak. Kita mulai dengan beberapa elemen, dan kami kembali dengan mereka. Efektif terdiri DOM pohon akan terlihat sebagai berikut:

1
<div id="#shadow-dialog">
2
	<slot name="header">
3
		<span slot="header">
4
			My header title
5
		</span>
6
	</slot>
7
	<slot name="content">
8
		<div slot="content">
9
			<strong>Some very important content</strong>
10
		</div>
11
	</slot>
12
</div>

Secara default, semua node root bayangan kami ditetapkan untuk default slot, jika ada. Default slot tidak memiliki nama. Jadi apa yang telah kita peroleh? Kami terintegrasi beberapa elemen transparan — Selamat! Tetapi yang lebih penting, markup asli kami tidak perlu mengubah untuk mengubah struktur, atribut atau tata letak kami terdiri DOM tree. Kita hanya perlu mengubah elemen-elemen yang ditambahkan ke akar bayangan, dan hanya itu. Kami memiliki lampu pada dasarnya front-end.

Sekarang beberapa orang mungkin berpikir bahwa kami memakai teknik yang sama pada sisi server. Dan tentu saja beberapa kerangka sisi klien juga mencoba untuk agregat kode seperti ini. Walaupun, ada beberapa perbedaan penting. Pertama, kita memiliki dukungan penuh browser (jika diterapkan). Kedua, sandboxing membuat render dengan aturan-aturan tertentu untuk modul yang mudah-tidak ada bentrokan dengan aturan CSS. Pada dasarnya dijamin bahwa modul bekerja pada setiap page. Tidak ada lagi debug untuk melihat mana aturan-aturan CSS mengganggu satu sama lain. Akhirnya, kami memproduksi banyak kode yang lebih baik. Sangat mudah untuk menghasilkan dan murah untuk transportasi, dan kita dapat mengharapkan kinerja yang lebih baik. 

Kesimpulan 

The DocumentFragment adalah pembantu yang berguna yang memiliki kemampuan untuk mengurangi jumlah operasi DOM secara drastis.   DOM secara drastis. Ini juga merupakan landasan penting teknologi modern, terutama di area komponen web. Ini telah menghasilkan dua teknologi yang benar-benar luar biasa: elemen <template> dan ShadowRoot .  Sementara yang pertama menyederhanakan banyak templating, memberi kita percepatan performa yang bagus dan cara yang elegan untuk mentransmisikan node pre-generated, yang terakhir adalah fondasi untuk komponen web. 

Apakah benar-benar layak mengetahui tentang DocumentFragment ? Mungkin belum. Jika kita menulis kerangka kerja atau perpustakaan maka itu pasti suatu keharusan, tetapi sebagian besar pengguna akan senang yang sangat mungkin sudah digunakan di perpustakaan front-end favorit mereka, seperti jQuery, Angular, dan lain-lain. Mereka semua menggunakan DocumentFragment di satu atau beberapa tempat untuk mengatasi potensi klik kinerja. Apakah DOM virtual lebih cepat dari yang asli?  Ya, tentu saja, tetapi mungkin tidak secepat tanpa menggunakan DocumentFragment untuk menggabungkan beberapa operasi. 

Referensi 

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.