In den Chrome-Entwicklertools werden jetzt auch Elemente der obersten Ebene unterstützt. Dies erleichtert Entwicklern das Debuggen ihres Codes, bei dem die Elemente der obersten Ebene verwendet werden.
In diesem Artikel wird beschrieben, was die Elemente der obersten Ebene sind, wie die Entwicklertools dabei helfen, den Inhalt der obersten Ebene zu visualisieren, um die DOM-Struktur mit den Elementen der obersten Ebene zu verstehen und zu debuggen, und wie die Unterstützung der oberen Ebenen in den Entwicklertools implementiert wird.
Was sind die oberste und die oberste Ebene?
Was genau passiert intern, wenn Sie ein <dialog>
als modales Fenster öffnen? 🤔
Es wird in einer obersten Ebene platziert. Inhalte der obersten Ebene werden über allen anderen Inhalten gerendert. Beispielsweise muss ein modales Dialogfeld über allen anderen DOM-Inhalten angezeigt werden, sodass der Browser dieses Element automatisch in einem "obersten Layer" rendert. und Autoren gezwungen werden, manuell gegen den Z-Index zu kämpfen. Ein oberstes Ebenenelement erscheint auch mit dem höchsten Z-Index über einem Element.
Die oberste Ebene kann als die höchste Stapelschicht beschrieben werden. Jedem Dokument ist ein einzelner Darstellungsbereich und daher auch eine einzelne oberste Ebene zugeordnet. In der obersten Ebene können sich mehrere Elemente gleichzeitig befinden. In diesem Fall werden sie übereinander gestapelt, wobei das letzte Element übereinander liegt. Mit anderen Worten, alle Elemente der obersten Ebene werden in einem Last In, First Out-Stapel (LIFO) in der obersten Ebene platziert.
Das <dialog>
-Element ist nicht das einzige Element, das der Browser in eine oberste Ebene rendert. Derzeit sind die obersten Ebenenelemente:
Pop-overs, modale Dialogfelder und Elemente im Vollbildmodus
Sehen Sie sich die folgende Dialogimplementierung an:
<main>
<button onclick="window.dialog.showModal();">Open Dialog</button>
</main>
<dialog id="dialog"></dialog>
Hier ist eine Demo mit einigen Dialogfeldern, bei denen Stile auf ihre Hintergründe angewendet wurden (siehe nachstehende Bilderrahmen):
Was ist ein Bilderrahmen?
Glücklicherweise gibt es eine Möglichkeit, den Inhalt unter dem obersten Layer-Element anzupassen.
Jedes Element auf der obersten Ebene hat ein CSS-Pseudoelement, das als Hintergrund bezeichnet wird.
Der Bilderrahmen ist ein Feld in der Größe des Darstellungsbereichs, das direkt unter jedem obersten Ebenenelement gerendert wird. Mit dem Pseudoelement ::backdrop
können Sie alles, was sich unter dem Element befindet, verdeckt, gestalten oder vollständig ausblenden, wenn es das oberste Element im obersten Layer ist.
Wenn Sie mehrere modale Elemente erstellen, zeichnet der Browser den Hintergrund direkt unter dem vordersten Element dieser Art und über andere Vollbildelemente.
So gestalten Sie einen Hintergrund:
/* The browser displays the backdrop only when the dialog.showModal() function opens the dialog.*/
dialog::backdrop {
background: rgba(255,0,0,.25);
}
Wie soll nur der erste Bilderrahmen angezeigt werden?
Jedes Element der obersten Ebene hat einen Hintergrund, der zu einem obersten Layer-Stapel gehört. Diese Hintergründe sind so konzipiert, dass sie sich überlappen. Wenn die Deckkraft eines Hintergrunds also nicht 100 % beträgt, sind die Hintergründe darunter sichtbar.
Wenn nur der erste Hintergrund im Stapel der obersten Ebene sichtbar sein muss, können Sie dies erreichen, indem Sie die Element-IDs im Stapel der obersten Ebene verfolgen.
Wenn das hinzugefügte Element nicht das erste Element im obersten Layer ist, wendet die Funktion, die beim Einfügen des Elements in die oberste Ebene aufgerufen wird, die Klasse hiddenBackdrop
auf das ::backdrop
an. Diese Klasse wird entfernt, wenn das Element aus der obersten Ebene entfernt wird.
Sehen Sie sich den Code in dieser Beispieldemo an:
Design der Unterstützung der obersten Ebene in den Entwicklertools
Mit der Unterstützung der Entwicklertools für die oberste Ebene können Entwickler das Konzept der obersten Ebene besser verstehen und visualisieren, wie sich der Inhalt der obersten Ebene ändert. Mithilfe dieser Funktionen können Entwickler Folgendes erkennen:
- Die Elemente in der obersten Ebene zu jeder Zeit und ihre Reihenfolge.
- Das Element, das sich an einer beliebigen Stelle oben im Stapel befindet.
Darüber hinaus hilft die Unterstützung der obersten Ebene in den Entwicklertools dabei, die Position des Hintergrund-Pseudoelements im obersten Layer-Stapel zu visualisieren. Auch wenn es sich nicht um ein Baumelement handelt, spielt es eine wichtige Rolle bei der Funktionsweise der obersten Ebene und kann für Entwickler nützlich sein.
Mit den Funktionen zur Unterstützung der obersten Ebene können Sie:
- Sie können jederzeit beobachten, welche Elemente sich im obersten Layer-Stapel befinden. Der Darstellungsstapel der obersten Ebene ändert sich dynamisch, wenn Elemente zur obersten Ebene hinzugefügt oder daraus entfernt werden.
- Sehen Sie sich die Position des Elements im obersten Ebenenstapel an.
- Zwischen Elementen der obersten Ebene springen Hintergrund-Pseudoelement in der Baumstruktur zum Element oder Hintergrund-Pseudoelement im Darstellungscontainer der obersten Ebene und umgekehrt.
Sehen wir uns an, wie diese Funktionen verwendet werden.
Container der obersten Ebene
Zur Visualisierung der Elemente der obersten Ebene wird in den Entwicklertools der Elementstruktur ein Container der obersten Ebene hinzugefügt. Sie befindet sich nach dem schließenden </html>
-Tag.
Mit diesem Container können Sie die Elemente im Stapel der obersten Ebene jederzeit beobachten. Der Container der obersten Ebene ist eine Liste von Links zu den Elementen der obersten Ebene und ihren Hintergründen. Der Darstellungsstapel der obersten Ebene ändert sich dynamisch, wenn Elemente zur obersten Ebene hinzugefügt oder daraus entfernt werden.
Um die Elemente der obersten Ebene in der Elementstruktur oder im Container der obersten Ebene zu finden, klicken Sie auf die Links von der Darstellung des Elements der obersten Ebene im Container der obersten Ebene zum selben Element in der Elementstruktur und zurück.
Wenn Sie vom Containerelement der obersten Ebene zum Baumelement der obersten Ebene springen möchten, klicken Sie neben dem Element im Container der obersten Ebene auf die Schaltfläche Anzeigen.
Wenn Sie vom Baumelement der obersten Ebene zum Link im Container der obersten Ebene springen möchten, klicken Sie neben dem Element auf das Badge Oberste Ebene.
Sie können jedes Badge deaktivieren, auch das oberste Ebene. Wenn du die Badges deaktivieren möchtest, klicke mit der rechten Maustaste auf ein Badge, wähle Badge-Einstellungen aus und entferne die Häkchen neben den Badges, die du ausblenden möchtest.
Reihenfolge der Elemente im Stapel der obersten Ebene
Im Container der obersten Ebene werden die Elemente wie im Stapel angezeigt, allerdings in umgekehrter Reihenfolge. Das Stapelelement steht ganz oben in der Elementliste des Containers der obersten Ebene. Das bedeutet, dass das letzte Element in der Containerliste der obersten Ebene das Element ist, mit dem Sie derzeit im Dokument interagieren können.
Die Logos neben den Baumelementen geben an, ob die Elemente zur obersten Ebene gehören und die Positionsnummer eines Elements im Stapel enthalten.
In diesem Screenshot besteht der oberste Ebenenstapel aus zwei Elementen. Das zweite Element befindet sich oben im Stapel. Wenn Sie das zweite Element entfernen, wird das erste nach oben verschoben.
Bilderrahmen im Container der obersten Ebene
Wie bereits erwähnt, verfügt jedes oberste Ebenenelement über ein CSS-Pseudoelement, das als Hintergrund bezeichnet wird. Sie können dieses Element gestalten, sodass es hilfreich ist, es ebenfalls zu überprüfen und seine Darstellung anzusehen.
In der Elementstruktur befindet sich ein Hintergrundelement vor dem schließenden Tag des Elements, zu dem es gehört. Im Container der obersten Ebene wird jedoch ein Hintergrundlink direkt über dem obersten Ebenenelement angezeigt, zu dem er gehört.
Änderungen an der DOM-Baumstruktur
ElementsTreeElement
, die Klasse, die für das Erstellen und Verwalten einzelner DOM-Baumelemente in den Entwicklertools verantwortlich ist, reichte nicht aus, um einen Container der obersten Ebene zu implementieren.
Um den Container der obersten Ebene als Knoten in der Baumstruktur anzuzeigen, haben wir eine neue Klasse hinzugefügt, die Entwicklertools-Baumelementknoten erstellt. Zuvor war die Klasse, die für das Erstellen der Entwicklertools-Elementstruktur verantwortlich ist, die jedes TreeElement
mit einem DOMNode
initialisiert wurde. Dies ist eine Klasse mit einem backendNodeId
und anderen Backend-bezogenen Attributen. backendNodeId
wiederum wird auf dem Back-End zugewiesen.
Der Containerknoten der obersten Ebene mit einer Liste von Links zu Elementen der obersten Ebene, die sich wie ein regulärer Baumelementknoten verhalten. Dieser Knoten ist jedoch kein „echter“ Der DOM-Knoten und das Back-End müssen den Containerknoten der obersten Ebene nicht erstellen.
Zum Erstellen eines Frontend-Knotens, der die oberste Ebene darstellt, haben wir einen neuen Frontend-Knotentyp hinzugefügt, der ohne DOMNode
erstellt wird. Dieses Containerelement der obersten Ebene ist der erste Frontend-Knoten ohne DOMNode
, d. h., es existiert nur im Frontend und weiß nicht vom Backend. mehr darüber erfahren. Um dasselbe Verhalten wie andere Knoten zu haben, haben wir eine neue TopLayerContainer
-Klasse erstellt, die die UI.TreeOutline.TreeElement
-Klasse erweitert, die für das Verhalten der Front-End-Knoten verantwortlich ist.
Um die gewünschte Platzierung zu erreichen, hängt die Klasse, die ein Element rendert, TopLayerContainer
als nächstes gleichgeordnetes Element des <html>
-Tags an.
Ein neues Badge für die oberste Ebene weist darauf hin, dass sich das Element in der obersten Ebene befindet. Es dient als Link zur Verknüpfung dieses Elements im TopLayerContainer
-Element.
Ursprüngliches Design
Zuerst war geplant, die Elemente der obersten Ebene in den Container der obersten Ebene zu duplizieren, anstatt eine Liste mit Links zu den Elementen zu erstellen. Wir haben diese Lösung nicht implementiert, weil das Abrufen der untergeordneten Elemente in den Entwicklertools funktioniert. Jedes Element verfügt über einen übergeordneten Zeiger, der zum Abrufen von untergeordneten Elementen verwendet wird, und es ist unmöglich, mehrere Zeiger zu haben. Daher können wir keinen Knoten haben, der ordnungsgemäß erweitert wird und alle untergeordneten Elemente an mehreren Stellen in der Baumstruktur enthält. Im Allgemeinen wurde das System nicht mit doppelten Unterstrukturen erstellt.
Der Kompromiss, den wir entwickelten, bestand darin, Links zu den Frontend-DOM-Knoten zu erstellen, anstatt diese Knoten zu duplizieren. Die Klasse, die für die Erstellung von Links zu Elementen in den Entwicklertools verantwortlich ist, ist ShortcutTreeElement
, wodurch die UI.TreeOutline.TreeElement
erweitert wird. ShortcutTreeElement
verhält sich genauso wie andere DOM-Baumelemente der Entwicklertools, hat aber keinen entsprechenden Knoten im Back-End und eine Schaltfläche, die mit einem ElementsTreeElement
verknüpft ist.
Jedes ShortcutTreeElement
zum Knoten der obersten Ebene hat ein untergeordnetes ShortcutTreeElement
, das mit der Darstellung eines Pseudoelements ::backdrop
in der DOM-Baumstruktur der Entwicklertools verknüpft ist.
Ursprüngliches Design:
Änderungen am Chrome DevTools Protocol (CDP)
Für die Implementierung der Unterstützung der obersten Ebene sind Änderungen am Chrome DevTools Protocol (CDP) erforderlich. CDP dient als Kommunikationsprotokoll zwischen den Entwicklertools und Chromium.
Wir müssen Folgendes hinzufügen:
- Ein Befehl, der jederzeit vom Front-End aufgerufen werden kann.
- Ein Ereignis, das auf dem Frontend von der Backend-Seite ausgelöst wird.
CDP: Befehl DOM.getTopLayerElements
Um die aktuellen Elemente der obersten Ebene anzuzeigen, benötigen wir einen neuen experimentellen CDP-Befehl, der eine Liste der Knoten-IDs der Elemente auf der obersten Ebene zurückgibt. DevTools ruft diesen Befehl immer dann auf, wenn die Entwicklertools geöffnet werden oder wenn sich die Elemente der obersten Ebene ändern. Der Befehl sieht folgendermaßen aus:
# 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
-Ereignis
Um die aktuelle Liste der Elemente der obersten Ebene zu erhalten, muss jede Änderung an den Elementen der obersten Ebene ein experimentelles CDP-Ereignis auslösen. Dieses Ereignis informiert das Front-End über die Änderung, das dann den DOM.getTopLayerElements
-Befehl aufruft und die neue Elementliste empfängt.
Das Ereignis sieht so aus:
# Called by the change of the top layer elements.
experimental event topLayerElementsUpdated
Überlegungen zu CDP
Es gab mehrere Möglichkeiten, die KDP-Unterstützung der obersten Ebene zu implementieren. Eine weitere Option, die wir in Betracht gezogen haben, bestand darin, ein Ereignis zu erstellen, das die Liste der Elemente der obersten Ebene zurückgibt, anstatt das Frontend nur über das Hinzufügen oder Entfernen eines Elements der obersten Ebene zu informieren.
Alternativ könnten wir zwei Ereignisse anstelle des Befehls erstellen: topLayerElementAdded
und topLayerElementRemoved
. In diesem Fall würden wir ein Element erhalten und müssten das Array der obersten Layer-Elemente im Frontend verwalten.
Derzeit ruft ein Front-End-Ereignis den Befehl getTopLayerElements
auf, um eine Liste aktualisierter Elemente abzurufen. Wenn wir jedes Mal, wenn ein Ereignis ausgelöst wird, eine Liste mit Elementen oder einem bestimmten Element senden, das die Änderung verursacht hat, können wir einen Schritt für den Aufruf des Befehls vermeiden.
In diesem Fall würde das Front-End jedoch die Kontrolle darüber verlieren, welche Elemente per Push übertragen werden.
Wir haben es auf diese Weise implementiert, da es unserer Meinung nach besser ist, wenn das Front-End entscheidet, wann Knoten der obersten Ebene angefordert werden. Wenn beispielsweise die oberste Ebene in der Benutzeroberfläche minimiert ist oder der Nutzer ein Entwicklertools-Steuerfeld ohne den Elementbaum verwendet, müssen die zusätzlichen Knoten nicht abgerufen werden, die sich tiefer in der Baumstruktur befinden könnten.