Dukungan lapisan atas di Chrome DevTools

Alina Varkki
Alina Varkki

Chrome DevTools menambahkan dukungan untuk elemen lapisan atas, sehingga memudahkan developer men-debug kode yang menggunakan elemen lapisan atas.

Artikel ini menjelaskan apa yang dimaksud dengan elemen lapisan atas, bagaimana DevTools membantu memvisualisasikan konten lapisan atas untuk memahami dan men-debug struktur DOM yang berisi elemen lapisan atas, dan bagaimana dukungan lapisan atas DevTools diimplementasikan.

Apakah yang dimaksud dengan elemen lapisan atas dan lapisan atas?

Apa yang sebenarnya terjadi secara internal ketika Anda membuka <dialog> sebagai modal? 🤔

Data tersebut ditempatkan ke lapisan atas. Konten lapisan atas dirender di atas semua konten lainnya. Misalnya, dialog modal harus muncul di atas semua konten DOM lainnya, sehingga browser otomatis merender elemen ini dalam 'lapisan atas', bukan memaksa penulis untuk melawan indeks z secara manual. Elemen lapisan teratas muncul di atas elemen bahkan dengan indeks z tertinggi.

Lapisan atas dapat dijelaskan sebagai 'lapisan tumpukan tertinggi'. Setiap dokumen memiliki satu area pandang terkait dan, oleh karena itu, juga satu lapisan atas. Beberapa elemen dapat berada di dalam lapisan atas secara bersamaan. Ketika itu terjadi, komponen-komponen itu ditumpuk di atas satu sama lain, yang terakhir di atas. Dengan kata lain, semua elemen lapisan atas ditempatkan dalam tumpukan masuk terakhir, keluar pertama (LIFO) di lapisan atas.

Elemen <dialog> bukan satu-satunya elemen yang dirender browser ke lapisan atas. Saat ini, elemen lapisan atas adalah: popover, dialog modal, dan elemen dalam mode layar penuh.

Periksa penerapan dialog berikut:

<main>
  <button onclick="window.dialog.showModal();">Open Dialog</button>
</main>
<dialog id="dialog"></dialog>

Berikut ini demo dengan beberapa dialog yang memiliki gaya yang diterapkan ke tampilan latarnya (tampilan latar dijelaskan di bawah):

Apa itu tampilan latar?

Untungnya, ada cara untuk menyesuaikan konten di bawah elemen lapisan atas.

Setiap elemen di lapisan atas memiliki elemen pseudo CSS yang disebut backdrop.

Tampilan latar adalah kotak ukuran area pandang yang dirender tepat di bawah elemen lapisan atas. Elemen pseudo ::backdrop memungkinkan Anda mengaburkan, menata gaya, atau menyembunyikan sepenuhnya semua yang terletak di bawah elemen saat elemen paling atas di lapisan atas.

Bila Anda membuat beberapa elemen sebagai modal, browser akan menggambar tampilan latar tepat di bawah elemen paling depan dan di atas elemen layar penuh lainnya.

Berikut adalah cara menata gaya tampilan latar:

/* The browser displays the backdrop only when the dialog.showModal() function opens the dialog.*/
dialog::backdrop {
    background: rgba(255,0,0,.25);
}

Bagaimana cara menampilkan tampilan latar pertama saja?

Setiap elemen lapisan atas memiliki tampilan latar milik tumpukan lapisan atas. Latar belakang ini dirancang untuk saling tumpang tindih, jadi jika opasitas tampilan latar tidak 100%, latar belakang di bawahnya akan terlihat.

Jika hanya tampilan latar pertama di tumpukan lapisan atas yang perlu terlihat, Anda dapat melakukannya dengan melacak pengidentifikasi item di tumpukan lapisan atas.

Jika elemen yang ditambahkan bukan yang pertama di lapisan atas, fungsi yang dipanggil saat elemen dimasukkan ke lapisan atas akan menerapkan class hiddenBackdrop ke ::backdrop. Class ini dihapus saat elemen dihapus dari lapisan atas.

Lihat kode dalam demo contoh ini:

Desain dukungan lapisan atas di DevTools

Dukungan DevTools untuk lapisan atas membantu developer memahami konsep lapisan atas dan memvisualisasikan bagaimana konten lapisan atas berubah. Fitur ini membantu developer mengidentifikasi hal berikut:

  • Elemen-elemen dalam lapisan atas setiap saat dan urutannya.
  • Elemen di bagian atas stack pada setiap titik.

Selain itu, dukungan lapisan atas DevTools membantu memvisualisasikan posisi elemen semu tampilan latar di tumpukan lapisan atas. Meskipun bukan elemen hierarki, lapisan ini berperan penting dalam cara kerja lapisan atas dan dapat berguna bagi developer.

Dengan fitur dukungan lapisan atas, Anda dapat:

  1. Amati elemen mana yang berada di tumpukan lapisan atas kapan saja. Tumpukan representasi lapisan atas berubah secara dinamis saat elemen ditambahkan atau dihapus dari lapisan atas.
  2. Lihat posisi elemen di tumpukan lapisan atas.
  3. Lompat dari elemen lapisan atas atau elemen semu tampilan latar elemen di hierarki ke elemen atau elemen semu tampilan latar dalam penampung representasi lapisan atas dan kembali ke elemen tersebut.

Mari kita lihat cara menggunakan fitur-fitur ini.

Penampung lapisan atas

Untuk membantu memvisualisasikan elemen lapisan atas, DevTools menambahkan container lapisan atas ke hierarki elemen. Kode ini berada setelah tag </html> penutup.

Penampung ini memungkinkan Anda untuk mengamati elemen di tumpukan lapisan atas kapan saja. Penampung lapisan atas adalah daftar tautan ke elemen lapisan teratas dan tampilan latarnya. Tumpukan representasi lapisan atas berubah secara dinamis saat elemen ditambahkan atau dihapus dari lapisan atas.

Untuk menemukan elemen lapisan atas dalam hierarki elemen atau penampung lapisan atas, klik tautan dari representasi elemen lapisan teratas dalam penampung lapisan atas ke elemen yang sama dalam hierarki elemen dan sebaliknya.

Untuk melompat dari elemen penampung lapisan atas ke elemen hierarki lapisan atas, klik tombol tampilkan di samping elemen dalam penampung lapisan atas.

Beralih dari tautan penampung lapisan atas ke elemen.

Untuk melompat dari elemen hierarki lapisan atas ke link di penampung lapisan atas, klik badge lapisan atas di samping elemen.

Beralih dari elemen ke tautan penampung lapisan teratas.

Anda dapat menonaktifkan badge apa pun, termasuk badge lapisan teratas. Untuk menonaktifkan badge, klik kanan badge, pilih Setelan badge, lalu hapus centang di samping badge yang ingin disembunyikan.

Menonaktifkan badge.

Urutan elemen dalam tumpukan lapisan atas

Kontainer lapisan atas menampilkan elemen seperti yang muncul dalam tumpukan, tetapi dalam urutan terbalik. Bagian atas elemen tumpukan adalah yang terakhir dalam daftar elemen penampung lapisan atas. Artinya elemen terakhir dalam daftar penampung lapisan atas adalah elemen yang saat ini dapat berinteraksi dengan Anda dalam dokumen.

Badge di samping elemen hierarki menunjukkan apakah elemen termasuk dalam lapisan atas dan berisi nomor posisi elemen dalam tumpukan.

Dalam screenshot ini, tumpukan lapisan atas terdiri dari dua elemen, dengan elemen kedua berada di bagian atas tumpukan. Jika Anda menghapus elemen kedua, elemen pertama akan dipindahkan ke paling atas.

Urutan elemen dalam tumpukan.

Tampilan latar di penampung lapisan atas

Seperti disebutkan di atas, setiap elemen lapisan atas memiliki elemen semu CSS yang disebut tampilan latar. Anda bisa menata gaya elemen ini, sehingga ada baiknya untuk juga memeriksanya dan melihat representasinya.

Di hierarki elemen, elemen tampilan latar berada sebelum tag penutup elemen tempatnya berada. Namun, di penampung lapisan atas, tautan tampilan latar tercantum tepat di atas elemen lapisan teratas tempat tautan tersebut berada.

Posisi tumpukan tampilan latar.

Perubahan pada hierarki DOM

ElementsTreeElement, class yang bertanggung jawab untuk membuat dan mengelola elemen hierarki DOM individual di DevTools, tidak cukup untuk mengimplementasikan penampung lapisan atas.

Untuk menampilkan container lapisan atas sebagai node dalam hierarki, kami menambahkan class baru yang membuat node elemen hierarki DevTools. Sebelumnya, class yang bertanggung jawab untuk membuat hierarki elemen DevTools yang diinisialisasi setiap TreeElement dengan DOMNode, yang merupakan class dengan backendNodeId dan properti terkait backend lainnya. Selanjutnya, backendNodeId akan ditetapkan di backend.

Node penampung lapisan atas, yang memiliki daftar link ke elemen lapisan atas, diperlukan untuk berperilaku sebagai node elemen hierarki reguler. Namun, node ini bukanlah node DOM 'sebenarnya' dan backend tidak perlu membuat node penampung lapisan atas.

Untuk membuat node frontend yang mewakili lapisan atas, kami menambahkan jenis node frontend baru yang dibuat tanpa DOMNode. Elemen penampung lapisan atas ini adalah node frontend pertama yang tidak memiliki DOMNode, yang berarti node tersebut hanya ada di frontend dan backend tidak 'mengetahui'nya. Agar memiliki perilaku yang sama dengan node lain, kami membuat class TopLayerContainer baru yang memperluas class UI.TreeOutline.TreeElement yang bertanggung jawab atas perilaku node frontend.

Untuk mencapai penempatan yang diinginkan, class yang merender elemen akan melampirkan TopLayerContainer sebagai pasangan berikutnya dari tag <html>.

Badge lapisan atas baru menunjukkan bahwa elemen berada di lapisan atas dan berfungsi sebagai link ke pintasan elemen ini di elemen TopLayerContainer.

Desain awal

Pada awalnya, rencananya adalah menduplikasi elemen lapisan atas ke dalam penampung lapisan atas, alih-alih membuat daftar tautan ke elemen tersebut. Kami tidak menerapkan solusi ini karena cara kerja pengambilan turunan elemen di DevTools. Setiap elemen memiliki pointer induk yang digunakan dalam mengambil turunan dan tidak mungkin memiliki beberapa pointer. Oleh karena itu, kita tidak dapat memiliki node yang diperluas dengan benar dan berisi semua turunan di beberapa tempat dalam hierarki. Secara umum, sistem tidak dibuat dengan mempertimbangkan sub-hierarki duplikat.

Penyusupan yang kami lakukan adalah membuat link ke node DOM frontend, bukan menduplikasi node tersebut. Class yang bertanggung jawab untuk membuat link ke elemen di DevTools adalah ShortcutTreeElement, yang memperluas UI.TreeOutline.TreeElement. ShortcutTreeElement memiliki perilaku yang sama dengan elemen hierarki DOM DevTools lainnya, tetapi tidak memiliki node yang sesuai di backend dan memiliki tombol yang terhubung ke ElementsTreeElement. Setiap ShortcutTreeElement ke node lapisan atas memiliki ShortcutTreeElement turunan yang tertaut ke representasi elemen pseudo ::backdrop di hierarki DOM DevTools.

Desain awal:

Desain awal.

Perubahan Protokol Chrome DevTools (CDP)

Untuk menerapkan dukungan lapisan atas, perubahan pada Protokol Chrome DevTools (CDP) diperlukan. CDP berfungsi sebagai protokol komunikasi antara DevTools dan Chromium.

Kita perlu menambahkan hal berikut:

  • Perintah untuk dipanggil dari frontend kapan saja.
  • Peristiwa yang akan dipicu di frontend dari sisi backend.

CDP: Perintah DOM.getTopLayerElements

Untuk menampilkan elemen lapisan atas saat ini, kita memerlukan perintah CDP eksperimental baru yang menampilkan daftar ID node elemen yang ada di lapisan atas. DevTools memanggil perintah ini setiap kali DevTools dibuka atau saat elemen lapisan atas berubah. Perintahnya terlihat seperti berikut:

  # Returns NodeIds of the current top layer elements.
  # Top layer renders closest to the user within a viewport, therefore, its elements always
  # appear on top of all other content.
  experimental command getTopLayerElements
    returns
      # NodeIds of the top layer elements.
      array of NodeId nodeIds

CDP: DOM.topLayerElementsUpdated peristiwa

Untuk mendapatkan daftar terbaru elemen lapisan atas, kita memerlukan setiap perubahan elemen lapisan atas untuk memicu peristiwa CDP eksperimental. Peristiwa ini memberi tahu frontend tentang perubahan yang kemudian memanggil perintah DOM.getTopLayerElements dan menerima daftar elemen baru.

Peristiwa tersebut akan terlihat seperti berikut:

  # Called by the change of the top layer elements.
  experimental event topLayerElementsUpdated

Pertimbangan CDP

Ada beberapa opsi tentang cara menerapkan dukungan CDP dari lapisan atas. Pilihan lain yang kami pertimbangkan adalah membuat peristiwa yang akan menampilkan daftar elemen lapisan atas, bukan hanya menginformasikan bagian depan tentang penambahan atau penghapusan elemen lapisan atas.

Atau, kita dapat membuat dua peristiwa, bukan perintah: topLayerElementAdded dan topLayerElementRemoved. Dalam hal ini, kita akan menerima sebuah elemen dan perlu mengelola array elemen lapisan atas di front end.

Saat ini, peristiwa frontend memanggil perintah getTopLayerElements untuk mendapatkan daftar elemen yang diperbarui. Jika kita mengirim daftar elemen atau elemen tertentu yang menyebabkan perubahan setiap kali peristiwa dipicu, kita dapat menghindari satu langkah untuk memanggil perintah. Namun, dalam hal ini, frontend akan kehilangan kontrol atas elemen mana yang didorong.

Kami menerapkannya dengan cara ini karena, menurut pendapat kami, akan lebih baik jika frontend memutuskan kapan harus meminta node lapisan atas. Misalnya, jika lapisan atas diciutkan di UI atau pengguna menggunakan panel DevTools yang tidak memiliki hierarki elemen, tidak perlu mendapatkan node tambahan yang bisa berada lebih dalam ke hierarki.