Kendalikan click butang dalaman, kemudian hantar CustomEvent bernama daripada hos komponen. Halaman pengguna mendengar pada hos itu dan membaca event.detail. Panduan ini membina demo pelayar setempat yang lengkap pada Mac dan menerangkan pilihan peristiwa yang diperlukan oleh setiap pendengar.
Tentukan pemberitahuan yang diperlukan oleh pengguna anda
Bagi komponen web JavaScript biasa, pengguna ialah halaman atau komponen induk yang menggunakan elemen tersuai anda. Dalam contoh ini, tugas khususnya ialah membolehkan pengguna bertindak balas apabila seseorang mengaktifkan butang dalaman, tanpa membuat kueri pada DOM bayangan komponen.
Contoh ini menggunakan jubin sintetik berlabel Tile A. Peristiwa awamnya ialah tile-activate, yang membawa itemId dan count pengaktifan. CustomEvent menyediakan medan detail untuk data aplikasi ini; nama peristiwa peka huruf besar-kecil. Kod penghantaran dan pendengar mesti menggunakan nama yang sama tepat. Dokumentasi pembina CustomEvent.
Anggap pilihan tersebut sebagai kontrak antara muka ringkas:
- Nama:
tile-activate. - Maksud: butang dalaman telah diaktifkan dan kiraan dikemas kini.
- Muatan:
detail.itemIdmengenal pasti jubin;detail.countmengandungi kiraan yang telah dikemas kini. - Asal: hos elemen tersuai menghantar pemberitahuan.
- Penghantaran: pengguna langsung dan pendengar nenek moyang boleh menerimanya, termasuk merentasi sempadan DOM bayangan yang mengelilingi komponen.
Ini ialah pilihan reka bentuk untuk contoh ini. Peristiwa yang berguna menerangkan tindakan yang penting kepada pengguna. Dengan itu, komponen boleh mengubah penanda dalamannya kemudian sambil mengekalkan antara muka pemberitahuan yang sama.
Bina dan buka contoh lengkap pada Mac anda
Anda memerlukan pelayar desktop terkini dan editor teks biasa. Tiada pemasangan pakej atau langkah binaan diperlukan untuk contoh satu fail ini. Contoh ini menggunakan elemen tersuai kendiri yang mewarisi HTMLElement, corak platform yang didokumenkan dalam bahagian elemen tersuai Standard HTML.
Dalam TextEdit, pilih File > New, kemudian Format > Make Plain Text. Tampal keseluruhan dokumen di bawah. Pilih File > Save, namakan fail itu component-click.html, dan pilih Use .html jika diminta. Ini ialah langkah yang didokumenkan oleh Apple untuk mencipta fail HTML dalam TextEdit. Bekerja dengan dokumen HTML dalam TextEdit pada Mac.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Component click notification</title>
</head>
<body>
<h1>Component click notification</h1>
<section id="demo">
<action-tile id="tile" item-id="tile-a"></action-tile>
<p id="direct-status">Direct listener: waiting</p>
<p id="parent-status">Parent listener: waiting</p>
</section>
<script>
class ActionTile extends HTMLElement {
constructor() {
super();
this._count = 0;
this._button = null;
this._root = this.attachShadow({ mode: "open" });
this._handleClick = () => {
this._count += 1;
this.dispatchEvent(new CustomEvent("tile-activate", {
detail: {
itemId: this.getAttribute("item-id"),
count: this._count
},
bubbles: true,
composed: true
}));
};
}
connectedCallback() {
if (!this._button) {
this._button = document.createElement("button");
this._button.type = "button";
this._button.textContent = "Activate Tile A";
this._root.append(this._button);
}
this._button.addEventListener("click", this._handleClick);
}
disconnectedCallback() {
this._button.removeEventListener("click", this._handleClick);
}
}
customElements.define("action-tile", ActionTile);
const tile = document.getElementById("tile");
const demo = document.getElementById("demo");
const directStatus = document.getElementById("direct-status");
const parentStatus = document.getElementById("parent-status");
tile.addEventListener("tile-activate", (event) => {
const { itemId, count } = event.detail;
directStatus.textContent =
`Direct listener: ${itemId}, activation ${count}`;
});
demo.addEventListener("tile-activate", (event) => {
const { itemId, count } = event.detail;
parentStatus.textContent =
`Parent listener: ${itemId}, activation ${count}`;
});
</script>
</body>
</html>
Buka fail yang disimpan dalam pelayar anda dan klik Activate Tile A. Hasil pertama yang dijangka ialah Direct listener: tile-a, activation 1 dan Parent listener: tile-a, activation 1. Setiap pengaktifan seterusnya menambah kedua-dua kiraan yang dipaparkan sebanyak satu. Ini ialah hasil yang dijangka daripada contoh tersebut, bukannya hasil ujian pelayar yang dilaporkan.
Urutan penting dapat dilihat dalam kod: kemas kini keadaan komponen, cipta pemberitahuan, hantar daripada this, dan biarkan pengguna mengemas kini antara muka sendiri. dispatchEvent() memanggil pendengar yang berkenaan secara segerak sebelum kembali, jadi pengguna melihat kiraan yang telah dikemas kini semasa pengendali mereka berjalan. Dokumentasi dispatchEvent.
Pilih pilihan gelembung dan sempadan bayangan yang betul
Sasaran penghantaran dan lokasi pendengar menentukan pilihan yang penting. Pendengar yang dilampirkan terus pada hos menerima peristiwa yang dihantar pada hos itu walaupun bubbles bernilai false. Pendengar nenek moyang biasa memerlukan gelembung. Untuk merentasi sempadan DOM bayangan, composed juga diperlukan. Nilai lalai asas bagi bubbles, composed dan cancelable semuanya false. Standard DOM: antara muka Event.
Jadual keputusan berikut diperoleh daripada peraturan perambatan tersebut. Jadual ini mengandaikan pendengar biasa yang didaftarkan tanpa capture dan tiada pengendali yang menghentikan perambatan.
| Tempat peristiwa tersuai bermula | Tempat pengguna mendengar | Konfigurasi untuk laluan itu |
|---|---|---|
| Hos komponen | Hos yang sama | Kedua-dua bendera tidak perlu bernilai true |
| Hos komponen | Nenek moyang biasa dalam pepohon yang sama | bubbles: true |
| Butang dalaman bayangan | Nenek moyang biasa di luar punca bayangan itu | bubbles: true, composed: true |
| Hos komponen di dalam pepohon bayangan lain | Nenek moyang biasa di luar punca bayangan yang mengelilinginya | bubbles: true, composed: true |
Dalam demo ini, this.dispatchEvent(...) memulakan pemberitahuan pada hos. Oleh itu, pemberitahuan itu tidak perlu keluar daripada punca bayangan komponen itu sendiri. composed: true membolehkan pemberitahuan digunakan merentasi sempadan bayangan komponen pengeliling jika jubin ini diletakkan di dalamnya kemudian. Jangkauan yang lebih luas itu patut menjadi sebahagian daripada antara muka awam secara sengaja. Dokumentasi sifat composed bagi Event.
Untuk eksperimen ringkas, tukar hanya bubbles: true kepada bubbles: false, simpan dan muat semula halaman. Selepas pengaktifan, status langsung sepatutnya dikemas kini manakala status induk kekal Parent listener: waiting. Pulihkan tetapan gelembung selepas itu. Menukar hanya composed kepada false sepatutnya membiarkan kedua-dua pendengar berfungsi dalam dokumen khusus ini kerana tiada satu pun laluan merentasi sempadan bayangan.
Kekalkan tingkah laku pemulaan dan penyambungan semula
Penghantaran peristiwa mungkin kelihatan betul pada mulanya, tetapi menghasilkan pemberitahuan pendua selepas komponen berpindah atau disambungkan semula. Jelaskan tanggungjawab penciptaan, penyambungan dan pembersihan.
Pembina memanggil super() terlebih dahulu, memulakan keadaan dan melampirkan punca bayangan. Pemaparan berlaku dalam connectedCallback(), dengan rujukan butang sedia ada sebagai pengawal supaya ia berjalan sekali sahaja. Pilihan ini mengikut keperluan Standard HTML untuk pembina serta panduannya agar pemulaan yang tidak boleh berulang dikawal apabila panggilan balik sambungan berjalan semula. Keperluan untuk pembina dan tindak balas elemen tersuai.
Komponen mendaftarkan pendengar klik dalamannya apabila disambungkan dan membuangnya apabila diputuskan sambungannya. Apabila disambungkan semula, komponen itu menggunakan semula butang sedia ada dan mengekalkan _count. Panggilan balik sambungan dan pemutusan sambungan ialah cangkuk kitar hayat yang dipanggil apabila elemen memasuki dan meninggalkan dokumen. Menggunakan elemen tersuai.
Fungsi _handleClick yang disimpan itu penting: pembuangan pendengar mesti mengenal pasti fungsi yang sama yang digunakan semasa pendaftaran, dengan tetapan capture yang sama. Mencipta fungsi anak panah baharu dalam panggilan pembuangan tidak akan mengenal pasti pendengar yang didaftarkan itu. Dokumentasi removeEventListener.
Jika anda menambah pendengar pada window, document atau sasaran luaran lain dalam komponen yang lebih besar, berikan pendengar tersebut pembersihan yang sama jelasnya. Asingkan perubahan kitar hayat daripada maksud pemberitahuan supaya penyambungan semula elemen tidak mengumumkan tindakan pengguna secara tidak sengaja.
Diagnosis pemberitahuan yang tiada atau berulang
Gunakan dua baris status yang kelihatan untuk mencari punca kegagalan sebelum mengubah bendera peristiwa. Baris tersebut membezakan masalah pemberitahuan komponen daripada masalah penghantaran kepada nenek moyang.
- Tiada satu pun status berubah: bandingkan nama peristiwa semasa penghantaran dan pendaftaran, kemudian periksa sama ada takrif elemen tersuai dan pengendali butang berjalan. Dalam dokumen ini, pendengar pengguna didaftarkan sebelum sebarang pengaktifan oleh pengguna.
- Hanya status langsung berubah: periksa
bubbles. Periksa juga sebarang pengendali perantaraan yang menghentikan perambatan. - Penghantaran gagal hanya apabila berada di dalam komponen lain: kenal pasti sempadan bayangan pada laluan itu dan periksa
composed. - Kiraan melonjak selepas penyambungan semula: periksa pendaftaran pendengar yang berulang, khususnya fungsi tanpa nama baharu yang dicipta setiap kali elemen disambungkan.
Fungsi tanpa nama yang berulang ialah objek pendengar berasingan, walaupun teks sumbernya sama. Rujukan fungsi yang stabil memudahkan pendaftaran dan pembersihan. addEventListener() juga membezakan pilihan capture bagi pendengar, yang mempengaruhi bila ia berjalan. Dokumentasi addEventListener.
click natif mungkin sudah sampai ke luar pepohon bayangan kerana klik yang dihantar oleh pelayar bersifat composed. Peristiwa tersuai yang berasingan berguna apabila pengguna memerlukan tindakan komponen bernama dan muatan yang ditakrifkan. Elakkan mengendalikan kedua-dua pemberitahuan sebagai tindakan aplikasi yang sama, melainkan penduaan itu disengajakan. Dokumentasi sifat composed bagi Event.
Akhir sekali, bezakan pemberitahuan daripada kebenaran untuk meneruskan dalam reka bentuk peristiwa anda. Contoh ini menambah kiraan sebelum penghantaran dan membiarkan peristiwa tidak boleh dibatalkan. Pengguna yang memanggil preventDefault() tidak dapat membatalkan kemas kini itu. Permintaan yang boleh dibatalkan memerlukan pelaksanaan khusus yang memeriksa nilai pulangan dispatchEvent() sebelum melaksanakan tindakan yang diminta. Nilai pulangan dispatchEvent.
Untuk tugas ini, kontrak lengkapnya ringkas: satu pengendali butang dalaman mengemas kini keadaan, satu peristiwa tersuai bernama dihantar daripada hos, dan pengguna membaca muatan yang didokumenkan. Pastikan pendengar langsung berfungsi dahulu, kemudian dayakan laluan perambatan yang benar-benar diperlukan oleh antara muka yang mengandungi komponen itu.
Sumber
- Standard HTML — Elemen tersuai — WHATWG.
- Standard DOM — WHATWG.
- CustomEvent: pembina CustomEvent() — MDN Web Docs.
- EventTarget: kaedah dispatchEvent() — MDN Web Docs.
- Event: sifat composed — MDN Web Docs.
- Menggunakan elemen tersuai — MDN Web Docs.
- EventTarget: kaedah addEventListener() — MDN Web Docs.
- EventTarget: kaedah removeEventListener() — MDN Web Docs.
- Bekerja dengan dokumen HTML dalam TextEdit pada Mac — Apple.