Cara Memuat Elemen Kustom | Trik CSS – Beragampengetahuan
Kami penggemar elemen khusus di sini. Desainnya membuatnya sangat cocok untuk pemuatan lambat, yang dapat meningkatkan kinerja.
Terinspirasi oleh eksperimen rekan kerja, saya baru-baru ini mulai menulis autoloader sederhana: setiap kali elemen khusus muncul di DOM, jika belum tersedia, kami memuat implementasi yang sesuai. Browser kemudian bertanggung jawab untuk memutakhirkan elemen-elemen tersebut dari sana.
Anda mungkin tidak benar-benar membutuhkan semua ini; biasanya ada cara yang lebih mudah. Jika digunakan dengan sengaja, teknik yang ditampilkan di sini mungkin masih berguna untuk perangkat Anda.
Untuk konsistensi, kami ingin pemuat otomatis kami juga menjadi elemen khusus – yang juga berarti kami dapat dengan mudah mengonfigurasinya melalui HTML. Tapi pertama-tama, mari kita telusuri elemen kustom yang belum terselesaikan itu:
class AutoLoader extends HTMLElement {
connectedCallback() {
let scope = this.parentNode;
this.discover(scope);
}
}
customElements.define("ce-autoloader", AutoLoader);
Dengan asumsi kita telah memuat modul ini sebelumnya (menggunakan async ideal), kita dapat menempatkan a <ce-autoloader> elemen masuk <body> file kami.Ini akan segera memulai proses penemuan untuk semua elemen anak <body>, yang sekarang membentuk elemen root kita.Kami dapat membatasi penemuan ke subpohon dokumen dengan menambahkan <ce-autoloader> ke elemen penampungnya masing-masing – faktanya, kita bahkan mungkin memiliki banyak contoh dari subpohon yang berbeda.
Tentu saja, kami masih harus menerapkan discover metode (sebagai AutoLoader Menghadiri kelas):
discover(scope) {
let candidates = [scope, ...scope.querySelectorAll("*")];
for(let el of candidates) {
let tag = el.localName;
if(tag.includes("-") && !customElements.get(tag)) {
this.load(tag);
}
}
}
Di sini kami memeriksa elemen root kami serta setiap keturunan (*). Jika ini adalah elemen khusus — seperti yang ditunjukkan oleh tag dengan tanda penghubung — yang belum ditingkatkan versinya, kami akan mencoba memuat definisi yang sesuai. Menanyakan DOM dengan cara ini bisa mahal, jadi kita harus berhati-hati. Kami dapat mengurangi beban pada utas utama dengan menunda pekerjaan ini:
connectedCallback() {
let scope = this.parentNode;
requestIdleCallback(() => {
this.discover(scope);
});
}
requestIdleCallback belum didukung secara universal, tetapi kita dapat menggunakan requestAnimationFrame Sebagai cadangan:
let defer = window.requestIdleCallback || requestAnimationFrame;
class AutoLoader extends HTMLElement {
connectedCallback() {
let scope = this.parentNode;
defer(() => {
this.discover(scope);
});
}
// ...
}
Sekarang kita dapat melanjutkan dan mengimplementasikan yang hilang load metode injeksi dinamis <script> elemen:
load(tag) {
let el = document.createElement("script");
let res = new Promise((resolve, reject) => {
el.addEventListener("load", ev => {
resolve(null);
});
el.addEventListener("error", ev => {
reject(new Error("failed to locate custom-element definition"));
});
});
el.src = this.elementURL(tag);
document.head.appendChild(el);
return res;
}
elementURL(tag) {
return `${this.rootDir}/${tag}.js`;
}
Perhatikan konvensi hardcode di elementURL. ini src URL atribut mengasumsikan direktori tempat semua definisi elemen khusus berada (mis. <my-widget> → /components/my-widget.js).Kita dapat membuat strategi yang lebih rumit, tetapi ini sudah cukup untuk tujuan kita. Mendelegasikan URL ini ke metode terpisah memungkinkan subkelas khusus proyek bila diperlukan:
class FancyLoader extends AutoLoader {
elementURL(tag) {
// fancy logic
}
}
Apa pun itu, perhatikan bahwa kami mengandalkan this.rootDirDi sinilah konfigurasi yang disebutkan di atas masuk. Mari tambahkan pengambil yang sesuai:
get rootDir() {
let uri = this.getAttribute("root-dir");
if(!uri) {
throw new Error("cannot auto-load custom elements: missing `root-dir`");
}
if(uri.endsWith(" { // remove trailing slash
return uri.substring(0, uri.length - 1);
}
return uri;
}
Anda mungkin berpikir observedAttributes Sekarang, itu tidak benar-benar membuat segalanya lebih mudah.ditambah pembaruan root-dir Sepertinya sesuatu yang tidak akan pernah kita butuhkan saat runtime.
Sekarang kita dapat – dan harus – mengonfigurasi katalog elemen kita: <ce-autoloader root-dir="/components">.
Dengan ini, pemuat otomatis kami melakukan tugasnya. Kecuali hanya berfungsi sekali, untuk elemen yang sudah ada saat autoloader diinisialisasi. Kami mungkin juga ingin mempertimbangkan elemen yang ditambahkan secara dinamis.itulah tempatnya MutationObserver Memainkan peran:
connectedCallback() {
let scope = this.parentNode;
defer(() => {
this.discover(scope);
});
let observer = this._observer = new MutationObserver(mutations => {
for(let { addedNodes } of mutations) {
for(let node of addedNodes) {
defer(() => {
this.discover(node);
});
}
}
});
observer.observe(scope, { subtree: true, childList: true });
}
disconnectedCallback() {
this._observer.disconnect();
}
Dengan cara ini, setiap kali elemen baru muncul di DOM, browser memberi tahu kita – atau lebih tepatnya, subpohon kita masing-masing – yang kemudian kita gunakan untuk memulai ulang proses penemuan. (Anda dapat berargumen bahwa kami menciptakan kembali elemen khusus di sini, dan Anda benar.)
Pemuat otomatis kami sekarang berfungsi penuh. Penyempurnaan di masa mendatang dapat menyelidiki potensi kondisi balapan dan menyelidiki pengoptimalan. Tapi untuk kebanyakan kasus, itu mungkin cukup baik. Beri tahu saya di komentar jika Anda memiliki pendekatan yang berbeda dan kami dapat membandingkan pendapat!
Contents
rencana pengembangan website
metode pengembangan website
jelaskan beberapa rencana untuk pengembangan website, proses pengembangan website, kekuatan dan kelemahan bisnis pengembangan website
, jasa pengembangan website, tahap pengembangan website, biaya pengembangan website
#Cara #Memuat #Elemen #Kustom #Trik #CSS