èªå®ä¹å ç´ çä¸ä¸ªéè¦æ¹é¢æ¯å°è£ ï¼å 为èªå®ä¹å ç´ ä»å®ä¹ä¸æ¥è¯´æ¯ä¸ç§å¯éç¨åè½ï¼å®å¯ä»¥è¢«æ¾ç½®å¨ä»»ä½ç½é¡µä¸ï¼å¹¶ä¸ææå®è½å¤æ£å¸¸å·¥ä½ãå æ¤ï¼å¾éè¦çä¸ç¹æ¯ï¼è¿è¡å¨é¡µé¢ä¸ç代ç ä¸åºè¯¥è½å¤éè¿ä¿®æ¹èªå®ä¹å ç´ çå é¨å®ç°èæå¤å°ç ´åå®ãå½±å DOMï¼Shadow DOMï¼å è®¸ä½ å°ä¸ä¸ª DOM æ éå å°ä¸ä¸ªå ç´ ä¸ï¼å¹¶ä¸ä½¿è¯¥æ çå é¨å¯¹äºå¨é¡µé¢ä¸è¿è¡ç JavaScript å CSS æ¯éèçã
æ¬æä»ç»äºä½¿ç¨å½±å DOM çåºç¡ç¥è¯ã
é«å±æ¬¡æ¦è§æ¬æåè®¾ä½ å·²ç»çæ DOMï¼ææ¡£å¯¹è±¡æ¨¡åï¼çæ¦å¿µââä¸ç§è¿æ¥èç¹çæ ç¶ç»æï¼ä»£è¡¨æ è®°ææ¡£ï¼é常æ¯å¨ web ææ¡£ä¸ç HTML ææ¡£ï¼ä¸åºç°çä¸åå ç´ åææ¬å符串ãä½ä¸ºç¤ºä¾ï¼è¯·èèä»¥ä¸ HTML çæ®µï¼
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>DOM 示ä¾</title>
</head>
<body>
<section>
<img src="dinosaur.png" alt="ä¸ä¸ªçº¢è²çé¸çé¾ã" />
<p>
è¿éæä»¬å°æ·»å ä¸ä¸ªå°
<a href="https://www.mozilla.org/">Mozilla 主页</a>ç龿¥
</p>
</section>
</body>
</html>
è¿ä¸ªç段çæäºä»¥ä¸ç DOM ç»æï¼ä¸å æ¬ä» å å«ç©ºæ ¼çææ¬èç¹ï¼ï¼
- HTML - HEAD - META charset="utf-8" - TITLE - #text: DOM ç¤ºä¾ - BODY - SECTION - IMG src="dinosaur.png" alt="ä¸ä¸ªçº¢è²çé¸çé¾ã" - P - #text: è¿éæä»¬å°æ·»å ä¸ä¸ªå° - A href="https://www.mozilla.org/" - #text: Mozilla 主页 - #text: ç龿¥
å½±å DOM å 许å°éèç DOM æ éå å°å¸¸è§ DOM æ ä¸çå ç´ ä¸ââè¿ä¸ªå½±å DOM å§äºä¸ä¸ªå½±åæ ¹ï¼å¨å ¶ä¹ä¸ä½ å¯ä»¥ç¨ä¸æ®é DOM ç¸åçæ¹å¼éå ä»»ä½å ç´ ã
æä¸äºå½±å DOM æ¯è¯éè¦æ³¨æï¼
ä½ å¯ä»¥ç¨ä¸éå½±åèç¹å®å
¨ç¸åçæ¹å¼æ¥å½±åå½±å DOM ä¸çèç¹ââä¾å¦æ·»å åèç¹åè®¾ç½®å±æ§ãä½¿ç¨ element.style.foo 对å个èç¹è¿è¡æ ·å¼è®¾ç½®ï¼æå°æ´ä¸ªå½±åæ å
çæ ·å¼æ·»å å°ä¸ä¸ª <style>
å
ç´ ä¸ãä¸åä¹å¤å¨äºå½±å DOM å
çææä»£ç é½ä¸ä¼å½±åå®çå¤é¨ï¼ä»è便äºå®ç°å°è£
ã
å¨å½±å DOM å web å¼åè
æä¾ä¹åï¼æµè§å¨å·²ç»ä½¿ç¨å®æ¥å°è£
å
ç´ çå
é¨ç»æã以 <video>
å
ç´ ä¸¾ä¾ï¼å®æ´é²äºé»è®¤æµè§å¨æ§ä»¶ãå¨ DOM ä¸ä½ åªè½çå° <video>
å
ç´ ï¼ä½å
¶å½±å DOM ä¸å
å«äºä¸ç³»åæé®åå
¶å®æ§ä»¶ãå½±å DOM è§èä½¿ä½ è½å¤æçºµèªå®ä¹å
ç´ çå½±å DOMã
ä¸é¢ç页é¢å
å«ä¸¤ä¸ªå
ç´ ï¼ä¸ä¸ª id
屿§ä¸º "host"
ç <div>
å
ç´ ï¼ä»¥åä¸ä¸ªå
å«äºä¸äºææ¬ç <span>
å
ç´ ï¼
<div id="host"></div>
<span>I'm not in the shadow DOM</span>
æä»¬å°ä½¿ç¨ "host"
å
ç´ ä½ä¸ºå½±å宿主ãæä»¬è°ç¨å®¿ä¸»ä¸ç attachShadow()
æ¥å建影å DOMï¼ç¶åå¯ä»¥åæä»¬å°èç¹æ·»å å°ä¸» DOM 䏿 ·å°èç¹æ·»å å°å½±å DOM ä¸ãå¨è¿ä¸ªç¤ºä¾ä¸ï¼æä»¬æ·»å äºå个 <span>
å
ç´ ï¼
const host = document.querySelector("#host");
const shadow = host.attachShadow({ mode: "open" });
const span = document.createElement("span");
span.textContent = "I'm in the shadow DOM";
shadow.appendChild(span);
ç»æçèµ·æ¥åè¿æ ·ï¼
JavaScript å°è£ç®åè¿å¯è½çèµ·æ¥å¹¶ä¸æä¹æ ·ãä½è®©æä»¬çç妿页é¢ä¸è¿è¡ç代ç è¯å¾è®¿é®å½±å DOM ä¸çå ç´ ä¼åçä»ä¹ã
è¿ä¸ªé¡µé¢å°±åä¸ä¸ä¸ªä¸æ ·ï¼åªæ¯æä»¬æ·»å äºä¸¤ä¸ª <button>
å
ç´ ã
<div id="host"></div>
<span>I'm not in the shadow DOM</span>
<br />
<button id="upper" type="button">å° span å
ç´ è½¬æ¢ä¸ºå¤§å</button>
<button id="reload" type="button">éæ°å è½½</button>
ç¹å»âå° span å
ç´ è½¬æ¢ä¸ºå¤§åâæé®å°æ¾å°é¡µé¢ä¸ææ <span>
å
ç´ å¹¶å°å®ä»¬çææ¬æ¹å为大åã ç¹å»âéæ°å è½½âæé®åªä¼éæ°å 载页é¢ï¼è¿æ ·ä½ å°±å¯ä»¥å次å°è¯ã
const host = document.querySelector("#host");
const shadow = host.attachShadow({ mode: "open" });
const span = document.createElement("span");
span.textContent = "I'm in the shadow DOM";
shadow.appendChild(span);
const upper = document.querySelector("button#upper");
upper.addEventListener("click", () => {
const spans = Array.from(document.querySelectorAll("span"));
for (const span of spans) {
span.textContent = span.textContent.toUpperCase();
}
});
const reload = document.querySelector("#reload");
reload.addEventListener("click", () => document.location.reload());
å¦æä½ ç¹å»âå° span å
ç´ è½¬æ¢ä¸ºå¤§åâï¼ä½ å°çå° Document.querySelectorAll()
å¹¶æ²¡ææ¾å°å¨æä»¬å½±å DOM ä¸å
ç´ ï¼å®ä»¬å¯¹é¡µé¢ä¸ç JavaScript æ¥è¯´åºæ¬ä¸æ¯éèçï¼
å¨ä¸é¢çä¾åä¸ï¼æä»¬å°ä¸ä¸ªåæ° { mode: "open" }
ä¼ å
¥ attachShadow()
ãå½ mode
设置为 "open"
æ¶ï¼é¡µé¢ä¸ç JavaScript å¯ä»¥éè¿å½±å宿主ç shadowRoot
屿§è®¿é®å½±å DOM çå
é¨ã
å¨è¿ä¸ªä¾åä¸ï¼å°±åä¹å䏿 ·ï¼HTML å
å«å½±å宿主ã主 DOM æ ä¸çä¸ä¸ª <span>
å
ç´ ä»¥å两个æé®ï¼
<div id="host"></div>
<span>I'm not in the shadow DOM</span>
<br />
<button id="upper" type="button">å° span å
ç´ è½¬æ¢ä¸ºå¤§å</button>
<button id="reload" type="button">éæ°å è½½</button>
è¿æ¬¡ï¼â大åâæé®ä½¿ç¨ shadowRoot
æ¥æ¾å° DOM ä¸ç <span>
å
ç´ ï¼
const host = document.querySelector("#host");
const shadow = host.attachShadow({ mode: "open" });
const span = document.createElement("span");
span.textContent = "I'm in the shadow DOM";
shadow.appendChild(span);
const upper = document.querySelector("button#upper");
upper.addEventListener("click", () => {
const spans = Array.from(host.shadowRoot.querySelectorAll("span"));
for (const span of spans) {
span.textContent = span.textContent.toUpperCase();
}
});
const reload = document.querySelector("#reload");
reload.addEventListener("click", () => document.location.reload());
è¿æ¬¡ï¼é¡µé¢ä¸è¿è¡ç JavaScript å¯ä»¥è®¿é®å½±å DOM å é¨ï¼
ä½¿ç¨ {mode: "open"}
åæ°ä¸ºé¡µé¢æä¾ä¸ç§ç ´åå½±å DOM å°è£
çæ¹æ³ãå¦æä½ ä¸å¸æç»é¡µé¢è¿ä¸ªè½åï¼ä¼ é {mode: "closed"}
ä½ä¸ºæ¿ä»£ï¼æ¤æ¶ shadowRoot
è¿å null
ã
ç¶èï¼ä½ ä¸åºå°è¿è§ä¸ºä¸ä¸ªå¼ºå¤§çå®å ¨æºå¶ï¼å 为å®å¯ä»¥è¢«ç»è¿ï¼æ¯å¦éè¿å¨é¡µé¢ä¸è¿è¡çæµè§å¨æ©å±ãè¿æ´å¤å°æ¯ä¸ä¸ªæç¤ºé¡µé¢ä¸åºè®¿é®å½±å DOM æ å é¨çä¸ç§æç¤ºã
CSS å°è£å¨è¿ä¸ªçæ¬ç页é¢ä¸ï¼HTML ä¸åå§çæ¬ç¸åï¼
<div id="host"></div>
<span>I'm not in the shadow DOM</span>
å¨ JavaScript ä¸ï¼æä»¬å建影å DOMï¼
const host = document.querySelector("#host");
const shadow = host.attachShadow({ mode: "open" });
const span = document.createElement("span");
span.textContent = "I'm in the shadow DOM";
shadow.appendChild(span);
è¿æ¬¡ï¼æä»¬å°å
·æé对页é¢ä¸ <span>
å
ç´ çä¸äº CSSï¼
span {
color: blue;
border: 1px solid black;
}
页é¢ç CSS ä¸ä¼å½±åå½±å DOM å çèç¹ï¼
å¨å½±å DOM å åºç¨æ ·å¼å¨è¿ä¸ªé¨åï¼æä»¬å°çå°ä¸¤ç§ä¸åçæ¹æ³æ¥å¨å½±å DOM æ ä¸åºç¨æ ·å¼ï¼
CSSStyleSheet
对象并å°å
¶éå å°å½±åæ ¹ã<template>
å
ç´ ç声æä¸æ·»å ä¸ä¸ª <style>
å
ç´ ãå¨è¿ä¸¤ç§æ åµä¸ï¼å½±å DOM æ ä¸å®ä¹çæ ·å¼å±éå¨è¯¥æ å ï¼æä»¥å°±å页颿 ·å¼å°±åä¸ä¼å½±åå½±å DOM ä¸çå ç´ ä¸æ ·ï¼å½±å DOM æ ·å¼ä¹ä¸ä¼å½±å页é¢ä¸å ¶å®å ç´ çæ ·å¼ã
å¯æé æ ·å¼è¡¨è¦ä½¿ç¨å¯æé æ ·å¼è¡¨ä¸ºå½±å DOM ä¸ç页é¢å ç´ è®¾ç½®æ ·å¼ï¼æä»¬å¯ä»¥ï¼
CSSStyleSheet
对象CSSStyleSheet.replace()
æ CSSStyleSheet.replaceSync()
设置å
¶å
容ShadowRoot.adoptedStyleSheets
æ¥æ·»å å°å½±åæ ¹å¨ CSSStyleSheet
ä¸å®ä¹çè§åå°å±éå¨å½±å DOM æ çå
é¨ï¼ä»¥åæä»¬å°å
¶åé
å°çä»»ä½å
¶å® DOM æ ã
è¿éï¼åæ ·æ¯å
å«å®¿ä¸»ï¼hostï¼åä¸ä¸ª <span>
ç HTMLï¼
<div id="host"></div>
<span>I'm not in the shadow DOM</span>
è¿æ¬¡æä»¬å°å建影å DOM å¹¶å°ä¸ä¸ª CSSStyleSheet
对象èµç»å®ï¼
const sheet = new CSSStyleSheet();
sheet.replaceSync("span { color: red; border: 2px dotted black;}");
const host = document.querySelector("#host");
const shadow = host.attachShadow({ mode: "open" });
shadow.adoptedStyleSheets = [sheet];
const span = document.createElement("span");
span.textContent = "I'm in the shadow DOM";
shadow.appendChild(span);
å½±å DOM æ ä¸å®ä¹çæ ·å¼ä¸ä¼åºç¨å°é¡µé¢çå ¶å®é¨åï¼
å¨<template>
声æä¸æ·»å <style>
å
ç´
æå»º CSSStyleSheet
对象çä¸ä¸ªæ¿ä»£æ¹æ³æ¯å°ä¸ä¸ª <style>
å
ç´ å
å«å¨ç¨äºå®ä¹ web ç»ä»¶ç <template>
å
ç´ ä¸ã
å¨è¿ç§æ
åµä¸ï¼HTML å
å« <template>
声æ
<template id="my-element">
<style>
span {
color: red;
border: 2px dotted black;
}
</style>
<span>I'm in the shadow DOM</span>
</template>
<div id="host"></div>
<span>I'm not in the shadow DOM</span>
å¨ JavaScript ä¸ï¼æä»¬å°å建影å DOM å¹¶å° <template>
çå
容添å å°å
¶ä¸ï¼
const host = document.querySelector("#host");
const shadow = host.attachShadow({ mode: "open" });
const template = document.getElementById("my-element");
shadow.appendChild(template.content);
åæ ·å°ï¼å¨ <template>
ä¸å®ä¹çæ ·å¼å±éå¨å½±å DOM æ å
ï¼è䏿¯å¨é¡µé¢çå
¶å®é¨åï¼
使ç¨åªç§æ¹å¼åå³äºä½ çåºç¨ç¨åºå个人å好ã
å建ä¸ä¸ª CSSStyleSheet
å¹¶éè¿ adoptedStyleSheets
å°å
¶èµç»å½±åæ ¹å
è®¸ä½ å建å䏿 ·å¼è¡¨å¹¶å°å
¶ä¸å¤ä¸ª DOM æ å
±äº«ãä¾å¦ï¼ä¸ä¸ªç»ä»¶åºå¯ä»¥å建åä¸ªæ ·å¼è¡¨ï¼ç¶åå°å
¶ä¸è¯¥åºçææèªå®ä¹å
ç´ å
±äº«ãæµè§å¨å°ä»
è§£æè¯¥æ ·å¼è¡¨ãæ¤å¤ï¼ä½ å¯ä»¥å¯¹æ ·å¼è¡¨è¿è¡å¨ææ´æ¹ï¼å¹¶å°æ´æ¹ä¼ æå°ä½¿ç¨è¡¨çææç»ä»¶ã
èå½ä½ 叿æ¯å£°æå¼çãéè¦è¾å°çæ ·å¼å¹¶ä¸ä¸éè¦å¨ä¸åç»ä»¶ä¹é´å
±äº«æ ·å¼çæ¶åï¼éå <style>
å
ç´ çæ¹æ³åé常éåã
å¦ææ²¡æå½±å DOM æä¾çå°è£ ï¼èªå®ä¹å ç´ å°å徿 æ³ä½¿ç¨ãåªéå¨æä¸ªé¡µé¢ä¸è¿è¡ä¸äº JavaScript æ CSSï¼å°±æå¯è½æ æé´ç ´åèªå®ä¹å ç´ çè¡ä¸ºæå¸å±ãä½ä¸ºèªå®ä¹å ç´ çå¼åè ï¼ä½ å°æ æ³ç¥ééç¨äºèªå®ä¹å ç´ å é¨ç鿩卿¯å¦ä¸ä½¿ç¨ä½ èªå®ä¹å ç´ ç页é¢ä¸åºç¨çéæ©å¨åçå²çªã
èªå®ä¹å
ç´ è¢«å®ç°ä¸ºä¸ä¸ªç±»ï¼å®å¯ä»¥ç»§æ¿ HTMLElement
æå HTMLParagraphElement
è¿æ ·çå
ç½® HTML å
ç´ ãé常ï¼èªå®ä¹å
ç´ æ¬èº«æ¯ä¸ä¸ªå½±å宿主ï¼è¯¥å
ç´ å¨å
¶æ ¹èç¹ä¸å建å¤ä¸ªå
ç´ ï¼ä»¥æä¾å
ç´ çå
é¨å®ç°ã
ä¸é¢ç示ä¾å建äºä¸ä¸ª <filled-circle>
èªå®ä¹å
ç´ ï¼è¯¥å
ç´ ä»
渲æä¸ä¸ªå¡«å
äºå®å¿é¢è²çåå½¢ã
class FilledCircle extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
// å建ä¸ä¸ªå½±åæ ¹
// èªå®ä¹å
ç´ èªèº«æ¯å½±å宿主
const shadow = this.attachShadow({ mode: "open" });
// å建å
é¨å®ç°
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
const circle = document.createElementNS(
"http://www.w3.org/2000/svg",
"circle",
);
circle.setAttribute("cx", "50");
circle.setAttribute("cy", "50");
circle.setAttribute("r", "50");
circle.setAttribute("fill", this.getAttribute("color"));
svg.appendChild(circle);
shadow.appendChild(svg);
}
}
customElements.define("filled-circle", FilledCircle);
<filled-circle color="blue"></filled-circle>
å¯¹äºæ´å¤ç¤ºä¾åæè¿°èªå®ä¹å ç´ å®ç°çä¸åæ¹é¢ï¼è¯·åè§æä»¬çèªå®ä¹å ç´ æåã
åè§RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4