Element: attachShadow() 方法
Baseline 廣泛可用 *
Element.attachShadow() 方法將一個 Shadow DOM 樹附加到指定的元素,並返回對其 ShadowRoot 的引用。
可以附加 Shadow DOM 的元素
請注意,你不能將 Shadow Root 附加到每種型別的元素上。出於安全原因,有些元素不能擁有 Shadow DOM(例如 <a>)。
以下是你可以附加 Shadow Root 的元素列表:
在一個已經是 Shadow Host 的元素上呼叫此方法
此方法可以在已具有宣告式 Shadow Root的元素上呼叫,前提是指定的模式 mode 與現有模式匹配。在這種情況下,已經存在的 ShadowRoot 將被清除並返回。這允許一些情況,例如,伺服器端渲染已經宣告式地建立了一個 Shadow Root,然後客戶端程式碼嘗試再次附加該根。
否則,在一個已經有 Shadow Root 的元素上呼叫 attachShadow() 將會丟擲異常。
語法
attachShadow(options)
引數
options-
一個包含以下欄位的物件:
模式-
一個字串,指定 Shadow DOM 樹的封裝模式。可以是以下之一:
open-
Shadow Root 的元素可以從根外部的 JavaScript 訪問,例如使用
Element.shadowRoot。jselement.attachShadow({ mode: "open" }); element.shadowRoot; // Returns a ShadowRoot obj closed-
禁止從外部 JavaScript 訪問封閉 Shadow Root 的節點。
jselement.attachShadow({ mode: "closed" }); element.shadowRoot; // Returns null
clonable可選-
一個布林值,指定 Shadow Root 是否可克隆:當設定為
true時,使用Node.cloneNode()或Document.importNode()克隆的 Shadow Host 將在副本中包含 Shadow Root。其預設值為false。 delegatesFocus可選-
一個布林值,當設定為
true時,指定緩解自定義元素可聚焦性問題的行為。當 Shadow DOM 中不可聚焦的部分被點選時,第一個可聚焦的部分將獲得焦點,並且 Shadow Host 將獲得任何可用的:focus樣式。其預設值為false。 serializable可選-
一個布林值,當設定為
true時,表示 Shadow Root 是可序列化的。如果設定,Shadow Root 可以透過呼叫Element.getHTML()或ShadowRoot.getHTML()方法並將options.serializableShadowRoots引數設定為true來序列化。其預設值為false。 slotAssignment可選-
一個字串,指定 Shadow DOM 樹的插槽分配模式。可以是以下之一:
命名-
元素會自動分配到此 Shadow Root 中的
<slot>元素。宿主中帶有slot屬性的任何後代,如果其值與此 Shadow Root 中<slot>的name屬性匹配,將被分配到該插槽。宿主中沒有slot屬性的任何頂級子元素,如果存在沒有name屬性的<slot>(“預設插槽”),將被分配到該插槽。 manual-
元素不會自動分配到
<slot>元素。相反,它們必須透過HTMLSlotElement.assign()手動分配。其預設值為named。
返回值
返回一個 ShadowRoot 物件。
異常
NotSupportedErrorDOMException-
當你嘗試將 Shadow Root 附加到以下元素時,可能會丟擲此錯誤:
- 不在 HTML 名稱空間中或無法附加 Shadow DOM 的元素。
- 其中元素定義靜態屬性
disabledFeatures的值已設定為"shadow"。 - 已經有一個未宣告式建立的 Shadow Root 的元素。
- 具有宣告式 Shadow Root但指定
mode與現有模式不匹配的元素。
示例
字數統計自定義元素
以下示例取自我們的 word-count-web-component 演示(也可線上檢視)。你可以看到我們在程式碼中間使用 attachShadow() 建立了一個 Shadow Root,然後將我們自定義元素的內容附加到其中。
// Create a class for the element
class WordCount extends HTMLParagraphElement {
constructor() {
// Always call super first in constructor
super();
// count words in element's parent element
const wcParent = this.parentNode;
function countWords(node) {
const text = node.innerText || node.textContent;
return text
.trim()
.split(/\s+/g)
.filter((a) => a.trim().length > 0).length;
}
const count = `Words: ${countWords(wcParent)}`;
// Create a shadow root
const shadow = this.attachShadow({ mode: "open" });
// Create text node and add word count to it
const text = document.createElement("span");
text.textContent = count;
// Append it to the shadow root
shadow.appendChild(text);
// Update count when element content changes
this.parentNode.addEventListener("input", () => {
text.textContent = `Words: ${countWords(wcParent)}`;
});
}
}
// Define the new element
customElements.define("word-count", WordCount, { extends: "p" });
停用 Shadow DOM
如果元素有一個名為 disabledFeatures 的靜態屬性,它是一個包含字串 "shadow" 的陣列,那麼 attachShadow() 呼叫將丟擲異常。
例如
class MyCustomElement extends HTMLElement {
// Disable shadow DOM for this element.
static disabledFeatures = ["shadow"];
constructor() {
super();
}
connectedCallback() {
// Create a shadow root.
// This will throw an exception.
const shadow = this.attachShadow({ mode: "open" });
}
}
// Define the new element
customElements.define("my-custom-element", MyCustomElement);
規範
| 規範 |
|---|
| DOM # dom-element-attachshadow |
瀏覽器相容性
載入中…
另見
ShadowRoot.modeShadowRoot.delegatesFocusShadowRoot.slotAssignment- 使用
<template>元素的shadowrootmode屬性宣告式地附加 Shadow Root - web.dev 上的宣告式 Shadow DOM (2023)