Chrome 開發人員工具新增對頂層元素的支援,方便開發人員針對使用頂層元素的程式碼進行偵錯。
本文將說明頂層元素、開發人員工具如何協助以視覺化方式呈現頂層圖層內容,進而瞭解並偵錯內含頂層圖層元素的 DOM 結構,以及開發人員工具的頂層支援實作方式。
頂層和頂層元素是什麼?
以互動模式開啟 <dialog>
時,內部會發生什麼情況?🤔
它位於頂層中。頂層內容會顯示在所有其他內容上方。舉例來說,強制回應對話方塊必須顯示在所有其他 DOM 內容上方,因此瀏覽器會自動將這個元素算繪到「頂層」而不是強製作者手動對抗 Z-index即使 Z-index 值最高,頂層元素仍會在元素上方顯示。
頂層可以描述為「最高堆疊層」。每份文件都有一個相關聯的可視區域,因此也只有一個頂層。 頂層圖層可同時包含多個元素。當這種情況發生時,這些元素會相互堆疊,最後一個按鈕會疊放在一起。換句話說,所有頂層元素都會放置在頂層圖層的「最後由上到」堆疊中。
<dialog>
元素不是瀏覽器算繪到頂層圖層的唯一元素。目前的頂層元素如下:
彈出式視窗、強制回應對話方塊和全螢幕模式中的元素。
檢查下列對話方塊實作:
<main>
<button onclick="window.dialog.showModal();">Open Dialog</button>
</main>
<dialog id="dialog"></dialog>
以下範例示範了幾個對話方塊,而且這些對話方塊的樣式已套用到背景 (如下所述):
什麼是背景幕?
幸好,您可以自訂頂層圖層元素底下的內容。
背景是檢視區大小的方塊,它會直接顯示在任何頂層圖層元素下方。使用 ::backdrop
虛擬元素時,您可以遮蔽、設定樣式,或完全隱藏位於頂層圖層的元素底下的所有內容。
將多個元素設為互動模式時,瀏覽器會在最前方的元素下方和其他全螢幕元素上方繪製背景。
以下是設定背景幕的樣式:
/* The browser displays the backdrop only when the dialog.showModal() function opens the dialog.*/
dialog::backdrop {
background: rgba(255,0,0,.25);
}
如何只顯示第一個背景幕?
每個頂層元素都有屬於頂層圖層堆疊的背景。這些背景都是互相重疊的,因此如果背景的透明度不是 100%,就可以看到底下的背景。
如果只需要顯示頂層堆疊中的第一個背景,可以在頂層堆疊中追蹤項目 ID,藉此達到目的。
如果新增的元素不是頂層圖層的第一個元素,則當元素放在頂層圖層時,該函式會呼叫 hiddenBackdrop
類別至 ::backdrop
。從頂層圖層移除元素時,也會一併移除這個類別。
查看以下範例中的程式碼:
開發人員工具的頂層支援設計
針對頂層層級的開發人員工具支援功能,可協助開發人員瞭解頂層概念,並以視覺化的方式呈現頂層內容的變化情形。這些功能可以協助開發人員識別以下項目:
- 頂端圖層中的元素隨時,以及其順序。
- 任何時間點位於堆疊頂端的元素。
此外,開發人員工具的頂層支援可將背景虛擬元素在頂層圖層堆疊中的位置視覺化。即使這並非樹狀結構元素,但頂層資料層的運作方式仍相當重要,並為開發人員提供實用協助。
有了頂層支援功能,您可以:
- 隨時查看頂層堆疊中的元素。隨著元素從頂層加入或移除,頂層表示法堆疊也會動態調整。
- 查看元素在頂層堆疊中的位置。
- 從頂層元素或元素跳出背景虛擬元素到頂層代表容器中的元素或背景虛擬元素。
一起來看看如何使用這些功能!
頂層容器
為了以視覺化方式呈現頂層元素,開發人員工具會在元素樹狀結構中新增頂層容器。位於 </html>
結尾標記之後。
這個容器可讓您隨時觀察頂層堆疊中的元素。頂層容器是頂層元素及其背景的連結清單。隨著元素從頂層加入或移除,頂層表示法堆疊也會動態調整。
如要在元素樹狀結構或頂層容器容器中找出頂層元素,請按一下頂層圖層容器中最上層元素的連結,前往元素樹狀結構和返回中的相同元素。
如要從頂層容器元素跳到頂層資料層元素,請在頂層容器中,按一下元素旁邊的「顯示」按鈕。
如要從頂層樹狀結構元素前往頂層容器中的連結,請按一下元素旁邊的頂層徽章。
您可以關閉任何徽章,包括頂層徽章。如要停用徽章,請在任一徽章上按一下滑鼠右鍵,選擇「徽章設定」,然後找出要隱藏的徽章並取消勾選旁邊的勾號。
頂層圖層堆疊中的元素順序
頂層容器會以相反順序顯示在堆疊中的元素。堆疊元素頂端是頂層容器元素清單中的最後一個元素。這表示頂層容器清單中的最後一個元素,就是您目前可以與文件中互動的元素。
樹狀結構元素旁邊的徽章會指出元素是否屬於頂層圖層,且包含堆疊中元素的位置編號。
在這張螢幕截圖中,頂層堆疊由兩個元素組成,第二個元素位於堆疊頂端。如果移除第二個元素,第一個元素會移至頂端。
頂層容器中的背景幕
如前所述,每個頂層元素都有稱為背景的 CSS 虛擬元素。您可以設定這個元素的樣式,方便一併檢查及查看元素的呈現方式。
在元素樹狀結構中,背景元素位於其所屬元素的結尾標記之前。不過,在頂層容器中,背景連結會列在所屬頂層元素的上方。
DOM 樹狀結構變更
ElementsTreeElement
這個類別負責在開發人員工具中建立及管理個別 DOM 樹狀結構元素,不足以導入頂層容器。
為了將頂層容器顯示為樹狀結構中的節點,我們新增了一個用來建立開發人員工具樹狀結構元素節點的新類別。先前負責建立開發人員工具元素樹狀結構的類別會使用 DOMNode
初始化每個 TreeElement
,後者是含有 backendNodeId
和其他後端相關屬性的類別。接著,已在後端指派 backendNodeId
。
頂層容器節點,具有頂層圖層元素的連結清單,運作時必須當做一般的樹狀結構元素節點。不過,這個節點並不是「真實」DOM 節點和後端不需要建立頂層容器節點。
為了建立代表頂層的前端節點,我們新增了一種在沒有 DOMNode
的情況下建立的前端節點。這個頂層容器元素是第一個沒有 DOMNode
的前端節點,意思是它只存在於前端,且後端並不知道給大家看為了與其他節點使用相同的行為,我們建立新的 TopLayerContainer
類別來擴充 UI.TreeOutline.TreeElement
類別,該類別負責處理前端節點的行為。
為了達到所需位置,用於算繪元素的類別會附加 TopLayerContainer
做為 <html>
標記的下一個同層。
新的頂層徽章表示元素位於頂層圖層,並做為 TopLayerContainer
元素中此元素捷徑的連結。
初始設計
我們起初打算將頂層容器元素複製到頂層容器,而非建立元素連結清單。由於在開發人員工具中擷取元素子項的方式,因此我們未實作這項解決方案。每個元素都有用來擷取子項的父項指標,而且無法有多個指標。因此,我們沒有可以適當展開,且包含樹狀結構中多個位置所有子項的節點。 一般而言,系統不會考慮重複的子樹狀結構。
我們所到的入侵是建立連至前端 DOM 節點的連結,而不是複製這些節點。在開發人員工具中建立元素連結的類別為 ShortcutTreeElement
,可擴充 UI.TreeOutline.TreeElement
。ShortcutTreeElement
的行為與其他開發人員工具 DOM 樹狀結構元素相同,但後端沒有對應節點,且具有連結至 ElementsTreeElement
的按鈕。
每個 ShortcutTreeElement
至頂層節點節點都有子項 ShortcutTreeElement
,可連結至開發人員工具 DOM 樹狀結構中 ::backdrop
虛擬元素的表示法。
初始設計:
Chrome 開發人員工具通訊協定 (CDP) 變更
如要導入頂層支援,必須變更 Chrome 開發人員工具通訊協定 (CDP)。CDP 是開發人員工具和 Chromium 之間的通訊協定。
我們必須新增下列項目:
- 隨時從前端呼叫的指令。
- 要在後端從後端觸發的事件。
CDP:DOM.getTopLayerElements
指令
如要顯示目前的頂層元素,我們需要新的實驗性 CDP 指令,傳回頂層元素的節點 ID 清單。每當開發人員工具開啟或頂層元素變更時,開發人員工具都會呼叫這個指令。這個指令如下所示:
# 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
個事件
為取得最新的頂層元素清單,每次變更頂層元素時,都必須觸發實驗性 CDP 事件。這個事件會通知變更前端,然後呼叫 DOM.getTopLayerElements
指令並接收新的元素清單。
事件如下所示:
# Called by the change of the top layer elements.
experimental event topLayerElementsUpdated
CDP 注意事項
針對頂層資料層支援 CDP 支援的實作方式有很多種。我們考慮的另一個選項是,所發表的事件可以傳回頂層圖層元素清單,而不只是告知前端新增或移除頂層圖層元素。
或者,我們可以建立兩個事件,而不是指令:topLayerElementAdded
和 topLayerElementRemoved
。在此案例中,我們會接收 元素,且需要管理前端頂層元素的陣列。
目前,前端事件會呼叫 getTopLayerElements
指令,取得更新後的元素清單。如果我們想在每次觸發事件時,傳送會導致變更的元素清單或特定元素,則可以避免呼叫 一個步驟。
不過在這種情況下,前端將失去控制權,無法決定要推送的元素。
我們相信,這種實作方式會因為前端決定要求頂層節點的時機比較好。例如,如果頂層使用者介面在 UI 中收合,或是使用者使用的開發人員工具面板沒有元素樹狀結構,您就不需要取得可在樹狀結構中深入探索的額外節點。