API Popover dan <dialog>
Elemen adalah dua fitur platform baru favorit saya. Faktanya, saya baru saja melakukannya [wrote a detailed overview of their use cases] Dan berbagai hal yang dapat Anda lakukan dengannya, bahkan mempelajari beberapa trik dalam prosesnya yang tidak dapat saya temukan didokumentasikan di tempat lain.
Saya akui bahwa satu-satunya hal yang saya tidak suka tentang popup dan dialog adalah bahwa keduanya dapat dengan mudah digabungkan menjadi satu API. Mereka mencakup kasus penggunaan yang berbeda (khususnya, kotak dialog biasanya berupa modal) tetapi praktiknya sangat mirip, namun implementasinya berbeda.
Nah, browser web kini bereksperimen dengan dua fitur HTML — secara teknis, keduanya disebut “perintah pemanggilan” — yang dirancang untuk memanggil popup, kotak dialog, dan segala macam tindakan tanpa menulis JavaScript. Namun, jika Anda… <>Dia melakukannya> Akses ke JavaScript, fitur baru — command
Dan commandfor
– Munculkan beberapa acara baru yang bisa kita dengarkan.
Perintah pemanggil? Saya yakin Anda memiliki pertanyaan, jadi mari selami lebih dalam.
Kami berada di zona eksperimental
Sebelum kita membahas lebih lanjut, kita membahas fitur eksperimental. Untuk menggunakan panggilan pengadilan hari ini pada bulan November 2024, Anda memerlukan Chrome <>Kenari> 134+ dengan enable-experimental-web-platform-features
Bendera sudah dipasang Enabled
Firefox <>Pada malam hari> 135+ dengan dom.element.invokers.enabled
Bendera sudah dipasang true
Atau safari <>Pratinjau teknologi> dengan InvokerAttributesEnabled
Bendera sudah dipasang true
.
Saya optimis bahwa kita akan mendapatkan cakupan dasar command
Dan commandfor
Tepat waktu mengingat seberapa baik ia mengabstraksi jenis pekerjaan yang saat ini memerlukan sejumlah besar skrip.
penting command
Dan commandfor
Menggunakan
Pertama, Anda perlu melakukannya <button>
Atau tombol <input>
Mirip dengan <input type="button">
atau <input type="reset">
. Setelah itu, pakai command
menjelaskan. itu command
Nilainya harus berupa nama perintah yang ingin Anda panggil tombolnya (misalnya, show-modal
). Selanjutnya, jatuhkan commandfor
Atribut yang menunjukkan dialog atau popup yang Anda targetkan id
.
<button command="show-modal" commandfor="dialogA">Show dialogA</button>
<dialog id="dialogA">...</dialog>
Dalam contoh ini saya punya <button>
elemen dengan command
Atribut disetel ke show-modal
Dan sebuah commandfor
Atribut disetel ke dialogA
yang sesuai dengan id
Dari a <dialog>
Elemen yang kami targetkan:
Mari selidiki kemungkinan nilai dari perintah pemanggil ini dan analisis apa yang mereka lakukan.
Perhatikan baik-baik nilai atribut
itu show-modal
value adalah perintah yang baru saja saya tunjukkan pada contoh terakhir ini. Secara khusus, ini adalah padanan yang disebut oleh HTML untuk JavaScript showModal()
jalan.
Manfaat utamanya adalah itu show-modal
Ini memungkinkan kita untuk, ya… <>ditampilkan> A <>bersyarat> Tanpa mengakses JavaScript secara langsung. Ya, ini hampir identik dengan cara kerja popup yang dipanggil HTML dengan filepopovertarget
Dan popovertargetaction
Tema, jadi sangat bagus jika “keseimbangan” seperti yang dijelaskan dalam penjelasan Open UI ditangani, dan terlebih lagi karena Anda dapat menggunakannya command
Dan commandfor
Perintah pemanggil untuk popup juga.
Tidak ada apa-apa show
Dia memesan Untuk memanggil show()
Untuk membuat kotak dialog modeless. Saya telah menyebutkan sebelumnya bahwa dialog modeless menjadi mubazir sekarang karena kita memiliki API Popover, terutama karena popup telah menjadi ::backdrop
s dan fitur mirip dialog lainnya. Prediksi saya yang berani adalah bahwa dialog tanpa naskah akan dihapuskan seiring berjalannya waktu.
itu close
Dia memesan Ini adalah HTML yang setara dengan JavaScript yang disebut close()
Metode yang digunakan untuk menutup kotak dialog. Anda mungkin bisa menebaknya berdasarkan namanya saja!
<dialog id="dialogA">
<!-- Close #dialogA -->
<button command="close" commandfor="dialogA">Close dialogA</button>
</dialog>
itu show-popover
, hide-popover
Dan toggle-popover
Nilai
<button command="show-popover" commandfor="id">
…panggilan showPopover()
yang merupakan hal yang sama:
<button popovertargetaction="show" popovertarget="id">
Demikian pula:
<button command="hide-popover" commandfor="id">
…panggilan hidePopover()
yang merupakan hal yang sama:
<button popovertargetaction="hide" popovertarget="id">
Akhirnya:
<button command="toggle-popover" commandfor="id">
…panggilan togglePopover()
yang merupakan hal yang sama:
<button popovertargetaction="toggle" popovertarget="id">
<!-- or <button popovertarget="id">, since ‘toggle’ is the default action anyway. -->
Saya tahu semua ini mungkin sulit untuk diatur dalam pikiran Anda, jadi mungkin sebuah tabel akan membantu menyatukan semuanya:
command |
Panggilan | popovertargetaction vs |
---|---|---|
show-popover |
showPopover() |
show |
hide-popover |
hidePopover() |
hide |
toggle-popover |
togglePopover() |
toggle |
Jadi… <>Ya>Popup sebenarnya dapat dipanggil menggunakan atribut HTML, menciptakan a command
Dan commandfor
Tidak semuanya berguna dalam konteks ini. Tapi seperti yang saya katakan, perintah callee juga dilengkapi dengan beberapa hal JavaScript yang berguna, jadi mari selami semua itu.
Dengarkan perintah menggunakan JavaScript
Perintah pemanggil dikirim a command
event ke target ketika tombol sumbernya diklik, yang dapat kita dengarkan dan kerjakan dalam JavaScript. Ini tidak diperlukan untuk <dialog>
Elemen close
Peristiwa, atau a popover
karakteristik toggle
atau beforetoggle
Event, karena kita sebenarnya bisa mendengarkannya, kan?
Misalnya, Dialog API tidak mengirimkan peristiwa When <dialog>
Dia muncul. Jadi, mari gunakan panggilan pengadilan untuk mendengarkan command
acara sebagai gantinya, lalu membacanya event.command
Untuk mengambil tindakan yang tepat.
// Select all dialogs
const dialogs = document.querySelectorAll("dialog");
// Loop all dialogs
dialogs.forEach(dialog => {
// Listen for close (as normal)
dialog.addEventListener("close", () => {
// Dialog was closed
});
// Listen for command
dialog.addEventListener("command", event => {
// If command is show-modal
if (event.command == "show-modal") {
// Dialog was shown (modally)
}
// Another way to listen for close
else if (event.command == "close") {
// Dialog was closed
}
});
});
Jadi callback memberi kita cara tambahan untuk bekerja dengan kotak dialog dan pop-up dan, dalam beberapa skenario, akan menjadi kurang detail. Namun dalam skenario lain, hal itu akan terjadi <>lagi> panjang. Pendekatan Anda harus bergantung pada apa yang Anda ingin lakukan pada kotak dialog dan pop-up.
Untuk kelengkapannya, berikut ini contoh popup, meskipun sebagian besar sama:
// Select all popovers
const popovers = document.querySelectorAll("[popover]");
// Loop all popovers
popovers.forEach(popover => {
// Listen for command
popover.addEventListener("command", event => {
// If command is show-popover
if (event.command == "show-popover") {
// Popover was shown
}
// If command is hide-popover
else if (event.command == "hide-popover") {
// Popover was hidden
}
// If command is toggle-popover
else if (event.command == "toggle-popover") {
// Popover was toggled
}
});
});
Kemampuan untuk mendengarkan show-popover
Dan hide-popover
Berguna karena kita harus menulis semacam logika “jika dibuka, lakukan ini, jika tidak lakukan itu” dari dalam file toggle
atau beforetoggle
pendengar acara atau toggle-popover
polisi. Tetapi <dialog>
elemen? Ya, mereka mendapat manfaat lebih dari itu command
Dan commandfor
Atribut dari apa yang mereka lakukan dari ini command
acara JavaScript.
Hal lain yang tersedia bagi kami melalui JavaScript adalah… event.source
yang merupakan tombol yang memanggil popover
atau <dialog>
:
if (event.command == "toggle-popover") {
// Toggle the invoker’s class
event.source.classList.toggle("active");
}
Anda juga bisa menyesuaikan command
Dan commandfor
Atribut menggunakan JavaScript:
const button = document.querySelector("button");
const dialog = document.querySelector("dialog");
button.command = "show-modal";
button.commandForElement = dialog; /* Not dialog.id */
…yang kurang detail dibandingkan:
button.command = "show-modal";
button.setAttribute("commandfor", dialog.id);
Buat pesanan khusus
itu command
Tema ini juga menerima perintah khusus yang diawali dengan dua tanda hubung (--
). Saya berasumsi ini menjadikannya seperti properti CSS khusus tetapi untuk acara JavaScript dan atribut HTML untuk pengendali acara. Catatan terakhir mungkin sedikit (atau pastinya banyak) kontroversial karena penggunaan atribut HTML untuk event handler dianggap praktik yang buruk. Tapi mari kita lihat saja, oke?
Perintah khusus terlihat seperti ini:
<button command="--spin-me-a-bit" commandfor="record">Spin me a bit</button>
<button command="--spin-me-a-lot" commandfor="record">Spin me a lot</button>
<button command="--spin-me-right-round" commandfor="record">Spin me right round</button>
const record = document.querySelector("#record");
record.addEventListener("command", event => {
if (event.command == "--spin-me-a-bit") {
record.style.rotate = "90deg";
} else if (event.command == "--spin-me-a-lot") {
record.style.rotate = "180deg";
} else if (event.command == "--spin-me-right-round") {
record.style.rotate = "360deg";
}
});
event.command
harus cocok dengan string putus-putus (--
) awalan.
Kami adalah popover
Dan <dialog>
Satu-satunya fitur yang mendukung perintah pemanggil?
Menurut Open UI, pemanggil menargetkan elemen tambahan seperti <details>
Itu tertunda dari rilis awal. Saya pikir ini karena dialog yang dipanggil oleh HTML dan API yang menyatukan dialog dan popup adalah hal yang harus dimiliki, sementara perintah lain (bahkan perintah khusus) tampak seperti kesepakatan yang bagus.
Namun, berdasarkan pengalaman (saya tidak bisa menahan diri!), browser web menerapkan penelepon tambahan pada tingkat yang berbeda-beda. Misalnya, <details>
Perintah berfungsi seperti yang diharapkan sementara… <select>
Sesuaikan pesanan event.command
(Misalnya, show-picker
) namun gagal memanggil metode tersebut (showPicker()
). Saya melewatkan semua ini pada awalnya karena MDN hanya menyebutkan dialog dan popup.
Antarmuka pengguna yang terbuka juga menunjukkan perintah <input type="file">
, <input type="number">
, <video>
, <audio>
dan metode yang terkait dengan layar penuh, tetapi menurut saya belum ada yang pasti saat ini.
Jadi, apa manfaat dari perintah pemanggil?
Ya, JavaScript yang digunakan jauh lebih sedikit, terutama jika lebih banyak callback yang dieksekusi seiring waktu. Selain itu, kita dapat mendengarkan perintah ini seolah-olah itu adalah peristiwa JavaScript. Namun yang lebih penting, callback hanya menyediakan lebih banyak cara untuk berinteraksi dengan API seperti Dialog dan Popover API. Singkatnya, tampaknya ada banyak “titik” dan “penyimpangan” yang sebenarnya bukan hal yang buruk.
Memanggil perintah: cara tambahan untuk bekerja dengan kotak dialog, popover… dan banyak lagi? Awalnya diterbitkan di CSS-Tricks, bagian dari keluarga DigitalOcean. Anda harus mendapatkan buletin.