Komponen web Bagian 3: templat dan impor html

Entri

Salam kolega. Artikel ini adalah artikel ketiga dan terakhir dalam serangkaian artikel tentang komponen web. Dua artikel pertama tersedia di:


Komponen web. Bagian 1: Elemen Kustom
Komponen web Bagian 2: Bayangan DOM

Artikel ini akan berbicara tentang elemen <template> dan juga tentang impor HTML.



Elemen Template HTML

Elemen <template> adalah alat yang memungkinkan Anda untuk menyimpan konten di sisi klien tanpa merendernya ke halaman, tetapi dengan kemampuan untuk menampilkannya selama eksekusi melalui JavaScript.


Saat mem-parsing halaman, konten elemen diproses hanya dalam hal validasi konten, tetapi tanpa merendernya (sesuai dengan spesifikasi, elemen ini tidak mewakili apa pun saat merender). Konten elemen dapat dikloning dan disisipkan ke dalam dokumen dari skrip, yang digunakan baik secara independen untuk standardisasi dan saat membuat komponen web.


Konten <template>

Konten <template>, serta node apa pun yang tidak memiliki konteks browser, tidak menerapkan persyaratan kepatuhan, kecuali persyaratan untuk kebenaran sintaks HTML dan XML. Ini berarti bahwa dalam konten template, misalnya, Anda dapat menentukan elemen img tanpa menentukan nilai atribut src dan alt, dengan demikian:


<template> <div> <img src="{{src}}" alt="{{alt}}"> </div> </template> 

namun, di luar elemen <template>, sintaksis seperti itu tidak valid. Dalam hal ini, melewatkan tag penutup </div> akan menjadi pelanggaran sintaks HTML dan tidak valid untuk konten <template>.


Semua elemen yang ditentukan di dalam tag <template> dalam kode html bukan anak-anaknya.


Browser saat membuat elemen <template> membuat DocumentFragment yang dokumennya disebut approptiate dokumen pemilik konten template, ditentukan oleh algoritma ini , dokumen di mana <template> ditentukan dan menunjukkan nilai properti .content yang dibuat oleh DocumentFragment.


Yaitu, properti .content dari elemen template berisi DocumentFragment, dan elemen yang ditentukan dalam kode html di dalam tag <template> adalah anak-anak dari DocumentFragment ini.


Dalam kasus ini, elemen <template>, seperti elemen lainnya, dapat ditambahkan dengan elemen turunan (appendChild () ), tetapi ini akan dianggap sebagai pelanggaran model konten template.


Template kloning

Ketika mengkloning konten templat, penting untuk diingat bahwa argumen pertama ke .cloneNode ([mendalam])
atau yang kedua di .importNode (externalNode, deep) harus ditransfer (sesuai spesifikasi, jika argumen tidak lulus, eksekusi lebih lanjut tidak boleh terjadi).


By the way, ya, terlepas dari kenyataan bahwa sebagian besar contoh menggunakan .cloneNode (), menggunakan .importNode () juga mungkin. Satu-satunya perbedaan adalah ketika dokumen diperbarui (untuk .cloneNode () - setelah memanggil appendChild (); untuk .importNode () - setelah kloning).


Tunjukkan pada saya kode ©

Menggunakan templat sangat sederhana. Saya akan melanjutkan contoh komponen tab, dengan kode yang saya kerjakan dalam contoh artikel sebelumnya.


Saya akan mulai dengan membuat dua elemen <template> di markup html dan mentransfer markup di dalamnya yang ada di metode .render () dari kelas TabNavigationItem dan TabContentItem (saya juga mengubah beberapa gaya, tetapi ini tidak mempengaruhi fungsi):


  <template id="tab-nav"> <style> :host{ padding: 10px; background-color: rgb(81,180,186); transition: background-color 1s; text-align: center; } :host-context(.active) { background-color: rgb(93, 209, 216); } a{ text-decoration: none; color: rgb(3,32,40); } </style> <a href="#${this._target}"><slot></slot></a> </template> 

dan:


  <template id="tab-content"> <style> :host { display: none; padding: 20px; width: 100%; background-color: rgb(255,212,201); } :host-context(.active){ display: block; } </style> <div><slot></slot></div> </template> 

Di konstruktor masing-masing kelas, saya akan menyimpan properti template. Untuk TabNavigationItem, ini akan menjadi:


  this.template = document.getElementById('tab-nav'); 

a untuk TabContentItem:


  this.template = document.getElementById('tab-content'); 

Dalam metode render () dari masing-masing kelas ini, saya akan menambahkan kode berikut, setelah menghapus entri .innerHTML:


  const content = this.template.content.cloneNode(true); this.shadowRoot.appendChild(content); 

Kode yang dihasilkan dapat ditemukan di sini.


Dalam contoh ini, kedua templat ditentukan dalam html, yang terlihat rumit dan tidak berdengung. Ini dengan lancar membawa kita ke topik:


Impor HTML

Impor adalah dokumen HTML yang terhubung sebagai sumber eksternal oleh dokumen HTML lain. Sistem hubungan antar dokumen dijelaskan dengan baik dalam draf spesifikasi dan bukan merupakan subjek dari artikel ini.

Skema umum terlihat pada gambar:


.

Untuk menerapkan impor, tipe baru ditambahkan ke tipe tautan HTML (nilai atribut rel).


Kata impor yang ditentukan dalam nilai atribut rel dari elemen <link> itu sendiri menciptakan tautan ke sumber daya yang diimpor (tipe default dari sumber daya adalah teks / html).


Elemen <link> mungkin memiliki atribut async.


Ekstensi yang ditawarkan oleh spesifikasi rancangan ditawarkan di API HTMLLinkElement: ditambahkan properti impor baca-saja yang berisi dokumen yang diimpor.


Properti dapat mengandung null dalam dua kasus: ketika <link> tidak mewakili impor atau <link> tidak ada dalam dokumen.


Spesifikasi menyatakan secara terpisah bahwa objek yang sama harus selalu dikembalikan.


Dalam konteks impor, ada yang disebut dokumen master, yaitu dokumen yang mengimpor sumber daya secara bersamaan tanpa menjadi sumber daya impor orang lain.

Kebijakan ContentSecurity dari dokumen tersebut harus membatasi semua impor. Jadi, jika Field Header Keamanan Konten diatur untuk diimpor, browser harus memberlakukan kebijakan dokumen master ke dokumen yang diimpor.


Dalam praktek

Untuk komponen tab, saya membuat folder template. Di dalamnya, saya akan membuat dua file di mana saya akan mentransfer markup komponen.


  <!--templates/tab-content.html--> <template id="tab-content"> <style> :host { display: none; padding: 20px; width: 100%; background-color: rgb(255,212,201); } :host-context(.active){ display: block; } </style> <div><slot></slot></div> </template> <!--templates/tab-nav.html--> <template id="tab-nav"> <style> :host{ padding: 10px; background-color: rgb(81,180,186); transition: background-color 1s; text-align: center; } :host-context(.active) { background-color: rgb(93, 209, 216); } a{ text-decoration: none; color: rgb(3,32,40); } </style> <a href="#${this._target}"><slot></slot></a> </template> 

Di <head> file index.html, saya mengimpor template:


  <link rel="import" href="templates/tab-nav.html" id="tab-nav"> <link rel="import" href="templates/tab-content.html" id="tab-content"> 

Saya menambahkan atribut id ke elemen <link>, karena saya perlu mengaksesnya dari js.
Sekarang, dalam konstruktor kelas TabNavigationItem dan TabContentItem, untuk mendapatkan dokumen templat, saya hanya perlu menemukan elemen <link> yang sesuai dan beralih ke properti impornya, setelah itu saya akan mencari templat yang sudah ada dalam dokumen yang diimpor:


  class TabNavigationItem extends HTMLElement { constructor() { super(); this._target = null; this.attachShadow({mode: 'open'}); const templateImport = document.getElementById('tab-nav').import; this.template = templateImport.getElementById('tab-nav'); } //... } class TabContentItem extends HTMLElement { constructor() { super(); this._target = null; this.attachShadow({mode: 'open'}); const templateImport = document.getElementById('tab-content').import; this.template = templateImport.getElementById('tab-content'); } //... } 

Versi final dapat diambil di sini .


Tentang Dukungan

Dukungan untuk templat HTML: Edge c 16, Firefox c 59, Chrome c 49, Safari c 11.
Dengan dukungan impor yang lebih menyedihkan: Chrome c 49.
Karena itu, contoh-contoh dari artikel ini hanya dapat dilihat di Chrome terbaru.


Ada polifilis:


Komponen web
Proyek polimer

Baca selengkapnya tentang templat dan impor:

Spesifikasi HTML
Spesifikasi HTML5
HTML Mengimpor spesifikasi konsep

Itu saja, terima kasih sudah menonton,
Tanya

Source: https://habr.com/ru/post/id414905/


All Articles