Memanggil perintah: cara tambahan untuk bekerja dengan kotak dialog, popover… dan banyak lagi?

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 EnabledFirefox <>Pada malam hari 135+ dengan dom.element.invokers.enabled Bendera sudah dipasang trueAtau 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 dialogAyang 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

Termasuk cadangan CodePen

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 ::backdrops 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-popoverDan 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 popovertargetactionvs
show-popover showPopover() show
hide-popover hidePopover() hide
toggle-popover togglePopover() toggle

Jadi… <>YaPopup 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.sourceyang 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.

Sumber