Web ç»ä»¶çä¸ä¸ªå ³é®ç¹æ§æ¯å建èªå®ä¹å ç´ ï¼å³ç± Web å¼å人åå®ä¹è¡ä¸ºç HTML å ç´ ï¼æ©å±äºæµè§å¨ä¸å¯ç¨çå ç´ éã
è¿ç¯æç« ä»ç»äºèªå®ä¹å ç´ ï¼å¹¶éè¿ä¸äºç¤ºä¾è¿è¡äºè¯¦ç»è¯´æã
èªå®ä¹å ç´ çç±»åæä¸¤ç§ç±»åçèªå®ä¹å ç´ ï¼
HTMLImageElement
æ HTMLParagraphElement
ãå®ä»¬çå®ç°å®ä¹äºæ åå
ç´ çè¡ä¸ºãHTMLElement
ãä½ å¿
é¡»ä»å¤´å¼å§å®ç°å®ä»¬çè¡ä¸ºãèªå®ä¹å
ç´ ä½ä¸ºä¸ä¸ªç±»æ¥å®ç°ï¼è¯¥ç±»å¯ä»¥æ©å± HTMLElement
ï¼å¨ç¬ç«å
ç´ çæ
åµä¸ï¼æè
ä½ æ³è¦å®å¶çæ¥å£ï¼å¨èªå®ä¹å
ç½®å
ç´ çæ
åµä¸ï¼ã
以䏿¯ä¸ä¸ªæå°èªå®ä¹å
ç´ çå®ç°ç¤ºä¾ï¼è¯¥å
ç´ å®å¶äº <p>
å
ç´ ï¼
class WordCount extends HTMLParagraphElement {
constructor() {
super();
}
// æ¤å¤ç¼åå
ç´ åè½
}
以䏿¯ä¸ä¸ªç¬ç«èªå®ä¹å ç´ çæå°å®ç°ï¼
class PopupInfo extends HTMLElement {
constructor() {
super();
}
// æ¤å¤ç¼åå
ç´ åè½
}
å¨ç±»çæé 彿°ä¸ï¼ä½ å¯ä»¥è®¾ç½®åå§ç¶æåé»è®¤å¼ï¼æ³¨åäºä»¶çå¬å¨ï¼çè³å建ä¸ä¸ªå½±åæ ¹ï¼shadow rootï¼ã卿¤å¤ï¼ä½ ä¸åºæ£æ¥å ç´ ç屿§æåå ç´ ï¼ä¹ä¸åºæ·»å æ°ç屿§æåå ç´ ãæå ³å®æ´çè¦æ±éï¼è¯·åé èªå®ä¹å ç´ æé 彿°å交äºè¡ä¸ºçè¦æ±ã
èªå®ä¹å ç´ çå½å¨æåè°ä¸æ¦ä½ çèªå®ä¹å ç´ è¢«æ³¨åï¼å½é¡µé¢ä¸ç代ç 以ç¹å®æ¹å¼ä¸ä½ çèªå®ä¹å ç´ äº¤äºæ¶ï¼æµè§å¨å°è°ç¨ä½ çç±»çæäºæ¹æ³ãéè¿æä¾è¿äºæ¹æ³çå®ç°ï¼è§èç§°ä¹ä¸ºçå½å¨æåè°ï¼ä½ å¯ä»¥è¿è¡ä»£ç æ¥ååºè¿äºäºä»¶ã
èªå®ä¹å ç´ çå½å¨æåè°å æ¬ï¼
connectedCallback()
ï¼æ¯å½å
ç´ æ·»å å°ææ¡£ä¸æ¶è°ç¨ãè§è建议å¼å人åå°½å¯è½å¨æ¤åè°ä¸å®ç°èªå®ä¹å
ç´ ç设å®ï¼è䏿¯å¨æé 彿°ä¸å®ç°ãdisconnectedCallback()
ï¼æ¯å½å
ç´ ä»ææ¡£ä¸ç§»é¤æ¶è°ç¨ãadoptedCallback()
ï¼æ¯å½å
ç´ è¢«ç§»å¨å°æ°ææ¡£ä¸æ¶è°ç¨ãattributeChangedCallback()
ï¼å¨å±æ§æ´æ¹ãæ·»å ãç§»é¤ææ¿æ¢æ¶è°ç¨ãæå
³æ¤åè°çæ´å¤è¯¦ç»ä¿¡æ¯ï¼è¯·åè§ååºå±æ§ååã以䏿¯ä¸ä¸ªè®°å½è¿äºçå½å¨æäºä»¶çæå°èªå®ä¹å ç´ ç¤ºä¾ï¼
// 为è¿ä¸ªå
ç´ å建类
class MyCustomElement extends HTMLElement {
static observedAttributes = ["color", "size"];
constructor() {
// å¿
é¡»é¦å
è°ç¨ super æ¹æ³
super();
}
connectedCallback() {
console.log("èªå®ä¹å
ç´ æ·»å è³é¡µé¢ã");
}
disconnectedCallback() {
console.log("èªå®ä¹å
ç´ ä»é¡µé¢ä¸ç§»é¤ã");
}
adoptedCallback() {
console.log("èªå®ä¹å
ç´ ç§»å¨è³æ°é¡µé¢ã");
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(`屿§ ${name} 已忴ã`);
}
}
customElements.define("my-custom-element", MyCustomElement);
注åèªå®ä¹å
ç´
è¦ä½¿èªå®ä¹å
ç´ å¨é¡µé¢ä¸å¯ç¨ï¼è¯·è°ç¨ Window.customElements
ç define()
æ¹æ³ã
define()
æ¹æ³æ¥å以ä¸åæ°ï¼
name
å ç´ çåç§°ãå¿ é¡»ä»¥å°å忝å¼å¤´ï¼å å«ä¸ä¸ªè¿å符ï¼å¹¶ç¬¦åè§è䏿æåç§°çå®ä¹ä¸ååºçä¸äºå ¶ä»è§åã
constructor
èªå®ä¹å ç´ çæé 彿°ã
options
ä»
对äºèªå®ä¹å
ç½®å
ç´ ï¼è¿æ¯ä¸ä¸ªå
å«åä¸ªå±æ§ extends
ç对象ï¼è¯¥å±æ§æ¯ä¸ä¸ªå符串ï¼å½åäºè¦æ©å±çå
ç½®å
ç´ ã
ä¾å¦ï¼ä»¥ä¸ä»£ç 注åäºå为 WordCount
çèªå®ä¹å
ç½®å
ç´ ï¼
customElements.define("word-count", WordCount, { extends: "p" });
以ä¸ä»£ç 注åäºå为 PopupInfo
çç¬ç«èªå®ä¹å
ç´ ï¼
customElements.define("popup-info", PopupInfo);
使ç¨èªå®ä¹å
ç´
䏿¦ä½ å®ä¹å¹¶æ³¨åäºèªå®ä¹å ç´ ï¼å°±å¯ä»¥å¨ä»£ç ä¸ä½¿ç¨å®ã
è¦ä½¿ç¨èªå®ä¹å
ç½®å
ç´ ï¼è¯·ä½¿ç¨å
ç½®å
ç´ ï¼ä½å°èªå®ä¹åç§°ä½ä¸º is
屿§çå¼ï¼
è¦ä½¿ç¨ç¬ç«èªå®ä¹å ç´ ï¼å°±å使ç¨å ç½®ç HTML å ç´ ä¸æ ·ï¼ä½¿ç¨èªå®ä¹åç§°å³å¯ï¼
<popup-info>
<!-- å
ç´ çå
容 -->
</popup-info>
ååºå±æ§åå
ä¸å ç½®å ç´ ä¸æ ·ï¼èªå®ä¹å ç´ å¯ä»¥ä½¿ç¨ HTML 屿§æ¥é ç½®å ç´ çè¡ä¸ºãä¸ºäºææå°ä½¿ç¨å±æ§ï¼å ç´ å¿ é¡»è½å¤ååºå±æ§å¼çååã为æ¤ï¼èªå®ä¹å ç´ éè¦å°ä»¥ä¸æåæ·»å å°å®ç°èªå®ä¹å ç´ çç±»ä¸ï¼
observedAttributes
çéæå±æ§ãè¿å¿
é¡»æ¯ä¸ä¸ªå
å«å
ç´ éè¦åæ´éç¥çææå±æ§åç§°çæ°ç»ãattributeChangedCallback()
çå½å¨æåè°çå®ç°ãattributeChangedCallback()
åè°å¨åå¨å
ç´ ç observedAttributes
屿§ä¸ç屿§è¢«æ·»å ãä¿®æ¹ãç§»é¤ææ¿æ¢æ¶è°ç¨ã
åè°æ¥åä¸ä¸ªåæ°ï¼
ä¾å¦ï¼ä¸é¢è¿ä¸ªç¬ç«èªå®ä¹å
ç´ å°è§å¯ä¸ä¸ª size
屿§ï¼å¹¶å¨å®ä»¬åçååæ¶è®°å½æ§å¼åæ°å¼ï¼
// 为è¿ä¸ªå
ç´ å建类
class MyCustomElement extends HTMLElement {
static observedAttributes = ["size"];
constructor() {
super();
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(`屿§ ${name} å·²ç± ${oldValue} åæ´ä¸º ${newValue}ã`);
}
}
customElements.define("my-custom-element", MyCustomElement);
请注æï¼å¦æå
ç´ ç HTML
声æå
å«ä¸ä¸ªè¢«è§å¯ç屿§ï¼é£ä¹å¨å±æ§è¢«åå§ååï¼attributeChangedCallback()
å°å¨å
ç´ ç声æé¦æ¬¡è§£ææ¶è¢«è°ç¨ãå æ¤ï¼å¨ä»¥ä¸ç¤ºä¾ä¸ï¼å³ä½¿å±æ§å乿²¡æè¢«æ´æ¹ï¼å½ DOM è¢«è§£ææ¶ï¼attributeChangedCallback()
ä¹ä¼è¢«è°ç¨ï¼
<my-custom-element size="100"></my-custom-element>
æå
³ä½¿ç¨ attributeChangedCallback()
ç宿´ç¤ºä¾ï¼è¯·åé
æ¬é¡µé¢ä¸ççå½å¨æåè°ã
卿¬æåçå ¶ä½é¨åï¼æä»¬å°çä¸äºç¤ºä¾èªå®ä¹å ç´ ãä½ å¯ä»¥å¨ web-components-examples ä»åºä¸æ¾å°ææè¿äºç¤ºä¾çæºä»£ç ï¼ä»¥åæ´å¤ç¤ºä¾ï¼å¹¶ä¸ä½ å¯ä»¥å¨ https://mdn.github.io/web-components-examples/ ä¸å®æ¶æ¥çå®ä»¬ã
ä¸ä¸ªç¬ç«èªå®ä¹å ç´é¦å
ï¼æä»¬æ¥çä¸ä¸ªç¬ç«èªå®ä¹å
ç´ ã<popup-info>
èªå®ä¹å
ç´ æ¥åå¾å徿 åææ¬å符串ä½ä¸ºå±æ§ï¼å¹¶å°å¾æ åµå
¥å°é¡µé¢ä¸ãå½ç¦ç¹å¨å¾æ 䏿¶ï¼å®ä¼å¨å¼¹åºçä¿¡æ¯æ¡ä¸æ¾ç¤ºææ¬ï¼ä»¥æä¾æ´å¤ä¸ä¸æä¿¡æ¯ã
é¦å
ï¼JavaScript æä»¶å®ä¹äºä¸ä¸ªå为 PopupInfo
çç±»ï¼è¯¥ç±»æ©å±äº HTMLElement
ç±»ã
// 为å½è¿ä¸ªå
ç´ å建ä¸ä¸ªç±»
class PopupInfo extends HTMLElement {
constructor() {
// å¿
é¡»é¦å
è°ç¨ super æ¹æ³
super();
}
connectedCallback() {
// åå»ºå½±åæ ¹
const shadow = this.attachShadow({ mode: "open" });
// å建å 个 span
const wrapper = document.createElement("span");
wrapper.setAttribute("class", "wrapper");
const icon = document.createElement("span");
icon.setAttribute("class", "icon");
icon.setAttribute("tabindex", 0);
const info = document.createElement("span");
info.setAttribute("class", "info");
// è·å屿§å
容ç¶åå°å
¶æ¾å
¥ info è¿ä¸ª span å
const text = this.getAttribute("data-text");
info.textContent = text;
// æå
¥å¾æ
let imgUrl;
if (this.hasAttribute("img")) {
imgUrl = this.getAttribute("img");
} else {
imgUrl = "img/default.png";
}
const img = document.createElement("img");
img.src = imgUrl;
icon.appendChild(img);
// å建ä¸äº CSS åºç¨äºå½±å DOM
const style = document.createElement("style");
console.log(style.isConnected);
style.textContent = `
.wrapper {
position: relative;
}
.info {
font-size: 0.8rem;
width: 200px;
display: inline-block;
border: 1px solid black;
padding: 10px;
background: white;
border-radius: 10px;
opacity: 0;
transition: 0.6s all;
position: absolute;
bottom: 20px;
left: 10px;
z-index: 3;
}
img {
width: 1.2rem;
}
.icon:hover + .info, .icon:focus + .info {
opacity: 1;
}
`;
// å°å建好çå
ç´ éå å°å½±å DOM ä¸
shadow.appendChild(style);
console.log(style.isConnected);
shadow.appendChild(wrapper);
wrapper.appendChild(icon);
wrapper.appendChild(info);
}
}
ç±»å®ä¹å
å«ç±»ç constructor()
æ¹æ³ï¼è¯¥æ¹æ³å§ç»ä»¥è°ç¨ super()
å¼å§ï¼ä»¥ä¾¿æ£ç¡®å»ºç«ååé¾ã
å¨ connectedCallback()
æ¹æ³å
é¨ï¼æä»¬å®ä¹äºå
ç´ è¿æ¥å° DOM æ¶å
ç´ å°å
·æçææåè½ãå¨è¿ç§æ
åµä¸ï¼æä»¬å°ä¸ä¸ªå½±åæ ¹éå å°èªå®ä¹å
ç´ ï¼ä½¿ç¨ä¸äº DOM æä½æ¥å建å
ç´ çå½±å DOM ç»æââç¶åå°å
¶éå å°å½±åæ ¹ââæåå°ä¸äº CSS éå å°å½±åæ ¹ä»¥è¿è¡æ ·å¼è®¾ç½®ãæä»¬ä¸å¨æé 彿°ä¸æ§è¡è¿é¡¹å·¥ä½ï¼å 为å¨è¿æ¥å° DOM ä¹åï¼å
ç´ ç屿§æ¯ä¸å¯ç¨çã
æåï¼æä»¬ä½¿ç¨å颿å°ç define()
æ¹æ³å¨ CustomElementRegistry
䏿³¨åæä»¬çèªå®ä¹å
ç´ ââå¨åæ°ä¸ï¼æä»¬æå®å
ç´ åç§°ï¼ç¶åå®ä¹å
¶åè½çç±»åç§°ï¼
customElements.define("popup-info", PopupInfo);
ç°å¨ï¼å®å·²ç»å¯ä»¥å¨æä»¬ç页é¢ä¸ä½¿ç¨äºã卿们ç HTML ä¸ï¼æä»¬å¯ä»¥åè¿æ ·ä½¿ç¨å®ï¼
<popup-info
img="img/alt.png"
data-text="Your card validation code (CVC)
is an extra security feature â it is the last 3 or 4 numbers on the
back of your card."></popup-info>
å¼ç¨å¤é¨æ ·å¼
å¨ä¸é¢ç示ä¾ä¸ï¼æä»¬ä½¿ç¨ <style>
å
ç´ ä¸ºå½±å DOM åºç¨æ ·å¼ï¼ä½ä½ ä¹å¯ä»¥ä» <link>
å
ç´ å¼ç¨å¤é¨æ ·å¼è¡¨ã卿¤ç¤ºä¾ä¸ï¼æä»¬å°ä¿®æ¹ <popup-info>
èªå®ä¹å
ç´ ä»¥ä½¿ç¨å¤é¨æ ·å¼è¡¨ã
ä¸é¢æ¯ç±»çå®ä¹ï¼
// 为è¿ä¸ªå
ç´ å建类
class PopupInfo extends HTMLElement {
constructor() {
// å¿
é¡»é¦å
è°ç¨ super æ¹æ³
super();
}
connectedCallback() {
// åå»ºå½±åæ ¹
const shadow = this.attachShadow({ mode: "open" });
// å建å 个 span
const wrapper = document.createElement("span");
wrapper.setAttribute("class", "wrapper");
const icon = document.createElement("span");
icon.setAttribute("class", "icon");
icon.setAttribute("tabindex", 0);
const info = document.createElement("span");
info.setAttribute("class", "info");
// è·å屿§å
容ç¶åå°å
¶æ¾å
¥ info è¿ä¸ª span å
const text = this.getAttribute("data-text");
info.textContent = text;
// æå
¥å¾æ
let imgUrl;
if (this.hasAttribute("img")) {
imgUrl = this.getAttribute("img");
} else {
imgUrl = "img/default.png";
}
const img = document.createElement("img");
img.src = imgUrl;
icon.appendChild(img);
// å°å¤é¨æ ·å¼æ·»å è³å½±å DOM
const linkElem = document.createElement("link");
linkElem.setAttribute("rel", "stylesheet");
linkElem.setAttribute("href", "style.css");
// å°å建好çå
ç´ éå å°å½±å DOM ä¸
shadow.appendChild(linkElem);
shadow.appendChild(wrapper);
wrapper.appendChild(icon);
wrapper.appendChild(info);
}
}
è¿ä¸åå§ç <popup-info>
示ä¾ç¸åï¼åªæ¯æä»¬ä½¿ç¨ <link>
å
ç´ é¾æ¥å°å¤é¨æ ·å¼è¡¨ï¼ç¶åå°å
¶æ·»å å°å½±å DOM ä¸ã
请注æï¼<link>
å
ç´ ä¸ä¼é»æ¢å½±åæ ¹çç»å¶ï¼å æ¤å¨æ ·å¼è¡¨å è½½æ¶å¯è½ä¼åºç°æªç»æ ·å¼åçå
容ï¼FOUCï¼ã
许å¤ç°ä»£æµè§å¨å¯¹äºä»å
Œ
±èç¹å
éç <style>
æ ç¾æå
·æç¸åææ¬çæ ç¾é½å®ç°äºä¸ç§ä¼åï¼ä½¿å®ä»¬å¯ä»¥å
±äº«å个å夿 ·å¼è¡¨ãéè¿è¿ç§ä¼åï¼å¤é¨åå
鍿 ·å¼çæ§è½åºè¯¥æ¯ç¸ä¼¼çã
ç°å¨è®©æä»¬çä¸ä¸ªèªå®ä¹å
ç½®å
ç´ çä¾åãè¿ä¸ªä¾åæ©å±äºå
ç½®ç <ul>
å
ç´ ï¼ä»¥æ¯æå±å¼åæå å表项ã
é¦å ï¼æä»¬å®ä¹äºè¿ä¸ªå ç´ çç±»ï¼
// 为è¿ä¸ªå
ç´ å建类
class ExpandingList extends HTMLUListElement {
constructor() {
// å¿
é¡»é¦å
è°ç¨ super æ¹æ³
// super() çè¿å弿¯å¯¹å½åå
ç´ çå¼ç¨
self = super();
}
connectedCallback() {
// è·åå½åèªå®ä¹ ul å
ç´ ç ul å li åå
ç´
// å
å« ul ç li å
ç´ å¯ä»¥æä¸ºå®¹å¨
const uls = Array.from(self.querySelectorAll("ul"));
const lis = Array.from(self.querySelectorAll("li"));
// éèææå ul
// å½ç¨æ·ç¹å»æ´é«çº§å«ç容卿¶ï¼è¿äºåè¡¨å°±ä¼æ¾ç¤ºåºæ¥
uls.forEach((ul) => {
ul.style.display = "none";
});
// ä»ç»è§å¯æ¯ä¸ªå¨ ul ä¸ç li å
ç´
lis.forEach((li) => {
// 妿è¿ä¸ª li æä¸ä¸ª ul ä½ä¸ºåå
ç´ ï¼å对å
¶è¿è¡è£
饰并添å ä¸ä¸ªç¹å»å¤çç¨åº
if (li.querySelectorAll("ul").length > 0) {
// æ·»å ä¸ä¸ªå±æ§ï¼ä»¥ä¾¿éè¿æ ·å¼ä½¿ç¨
// æ¥æ¾ç¤ºæå¼æå
³éç徿
li.setAttribute("class", "closed");
// å° li å
ç´ çææ¬å
裹å¨ä¸ä¸ªæ°ç span å
ç´ ä¸
// è¿æ ·æä»¬å°±å¯ä»¥å°æ ·å¼åäºä»¶å¤çç¨åºåé
ç» span
const childText = li.childNodes[0];
const newSpan = document.createElement("span");
// ä» li å¤å¶ææ¬å° spanï¼è®¾ç½®å
æ æ ·å¼
newSpan.textContent = childText.textContent;
newSpan.style.cursor = "pointer";
// 为è¿ä¸ª span æ·»å äºä»¶å¤çç¨åº
newSpan.addEventListener("click", (e) => {
// span çä¸ä¸ä¸ªå
å¼å
ç´ åºè¯¥æ¯ ul
const nextul = e.target.nextElementSibling;
// 忢å¯è§ç¶æå¹¶æ´æ° ul ç class 屿§
if (nextul.style.display == "block") {
nextul.style.display = "none";
nextul.parentNode.setAttribute("class", "closed");
} else {
nextul.style.display = "block";
nextul.parentNode.setAttribute("class", "open");
}
});
// æ·»å span å¹¶ä» li ä¸ç§»é¤çº¯ææ¬èç¹
childText.parentNode.insertBefore(newSpan, childText);
childText.parentNode.removeChild(childText);
}
});
}
}
请注æï¼è¿æ¬¡æä»¬æ©å±çæ¯ HTMLUListElement
ï¼è䏿¯ HTMLElement
ãè¿æå³çæä»¬è·å¾äºå表çé»è®¤è¡ä¸ºï¼åªéå®ç°èªå·±çå®å¶ã
ä¸ä¹å䏿 ·ï¼å¤§é¨å代ç é½å¨ connectedCallback()
çå½å¨æåè°ä¸ã
æ¥ä¸æ¥ï¼æä»¬ä½¿ç¨ä¸ä¹åç¸åç define()
æ¹æ³æ³¨åå
ç´ ï¼åªæ¯è¿æ¬¡å®è¿å
æ¬ä¸ä¸ªé项对象ï¼è¯¦ç»è¯´æäºæä»¬çèªå®ä¹å
ç´ ä»åªä¸ªå
ç´ ç»§æ¿ï¼
customElements.define("expanding-list", ExpandingList, { extends: "ul" });
å¨ Web ææ¡£ä¸ä½¿ç¨å ç½®å ç´ çèµ·æ¥ä¹æäºä¸åï¼
<ul is="expanding-list">
â¦
</ul>
ä½ ä½¿ç¨ <ul>
å
ç´ ä¸å¾å¸¸ä¸æ ·ï¼ä½å¨ is
屿§å
æå®èªå®ä¹å
ç´ çåç§°ã
请注æï¼å¨è¿ç§æ
åµä¸ï¼æä»¬å¿
须确ä¿å®ä¹èªå®ä¹å
ç´ çèæ¬å¨ DOM å®å
¨è§£æåæ§è¡ï¼å 为 connectedCallback()
å¨å±å¼çå表被添å å° DOM æ¶å°±ä¼è¢«è°ç¨ï¼èæ¤æ¶å
¶åå
ç´ å°æªæ·»å ï¼å æ¤ querySelectorAll()
è°ç¨å°æ¾ä¸å°ä»»ä½é¡¹ãç¡®ä¿è¿ä¸ç¹çä¸ç§æ¹æ³æ¯å¨å
å«èæ¬çè¡ä¸æ·»å defer 屿§ï¼
<script src="main.js" defer></script>
çå½å¨æåè°
å°ç®å为æ¢ï¼æä»¬åªçå°äºä¸ä¸ªçå½å¨æåè°çå®é
åºç¨ï¼connectedCallback()
ã卿åä¸ä¸ªç¤ºä¾ââ<custom-square>
ââä¸ï¼æä»¬å°çå°ä¸äºå
¶ä»çåè°ã<custom-square>
ç¬ç«èªå®ä¹å
ç´ ç»å¶ä¸ä¸ªæ£æ¹å½¢ï¼å
¶å¤§å°åé¢è²ç±ä¸¤ä¸ªå为 "size"
å "color"
ç屿§ç¡®å®ã
å¨ç±»çæé 彿°ä¸ï¼æä»¬å°å½±å DOM éå å°å
ç´ ä¸ï¼ç¶ååéå 空ç <div>
å <style>
å
ç´ å°å½±åæ ¹ä¸ï¼
constructor() {
// å¿
é¡»é¦å
è°ç¨ super æ¹æ³
super();
const shadow = this.attachShadow({ mode: "open" });
const div = document.createElement("div");
const style = document.createElement("style");
shadow.appendChild(style);
shadow.appendChild(div);
}
è¿ä¸ªç¤ºä¾çå
³é®å½æ°æ¯ updateStyle()
ââ宿¥åä¸ä¸ªå
ç´ ï¼è·åå
¶å½±åæ ¹ï¼æ¾å°å®ç <style>
å
ç´ ï¼ç¶åæ·»å width
ãheight
å background-color
å°æ ·å¼ä¸ã
function updateStyle(elem) {
const shadow = elem.shadowRoot;
shadow.querySelector("style").textContent = `
div {
width: ${elem.getAttribute("size")}px;
height: ${elem.getAttribute("size")}px;
background-color: ${elem.getAttribute("color")};
}
`;
}
å®é
çæ´æ°é½æ¯ç±çå½å¨æåè°å¤ççãconnectedCallback()
æ¯æ¬¡å°å
ç´ æ·»å å° DOM æ¶é½ä¼è¿è¡ä¸æ¬¡ââå¨è¿éï¼æä»¬è¿è¡ updateStyle()
彿°ï¼ä»¥ç¡®ä¿æ£æ¹å½¢çæ ·å¼ä¸å
¶å±æ§ä¸å®ä¹çä¸è´ï¼
connectedCallback() {
console.log("èªå®ä¹æ£æ¹å½¢å
ç´ æ·»å è³é¡µé¢ã");
updateStyle(this);
}
disconnectedCallback()
å adoptedCallback()
åè°å¨å
ç´ ä» DOM ä¸ç§»é¤æç§»å¨å°ä¸å页颿¶è®°å½æ¶æ¯å°æ§å¶å°ï¼ä»¥éç¥æä»¬ï¼
disconnectedCallback() {
console.log("èªå®ä¹æ£æ¹å½¢å
ç´ ä»é¡µé¢ä¸ç§»é¤ã");
}
adoptedCallback() {
console.log("èªå®ä¹æ£æ¹å½¢å
ç´ ç§»å¨è³æ°é¡µé¢ã");
}
attributeChangedCallback()
åè°å¨å
ç´ ç屿§ä»¥æç§æ¹å¼æ´æ¹æ¶è¿è¡ãæ£å¦ä½ ä»å
¶åæ°ä¸çå°ç飿 ·ï¼å¯ä»¥åç¬å¤ç屿§ï¼æ¥çå®ä»¬çåç§°ä»¥åæ§çåæ°ç屿§å¼ãä¸è¿å¨è¿ç§æ
åµä¸ï¼æä»¬åªæ¯å次è¿è¡ updateStyle()
彿°ï¼ä»¥ç¡®ä¿æ£æ¹å½¢çæ ·å¼æ ¹æ®æ°ç弿´æ°ï¼
attributeChangedCallback(name, oldValue, newValue) {
console.log("èªå®ä¹æ£æ¹å½¢å
ç´ ç屿§å·²åæ´ã");
updateStyle(this);
}
请注æï¼è¦å¨å±æ§æ´æ¹æ¶è§¦å attributeChangedCallback()
åè°ï¼å¿
é¡»è§å¯è¿äºå±æ§ãè¿éè¿å¨èªå®ä¹å
ç´ ç±»å
æå®ä¸ä¸ª static get observedAttributes()
æ¹æ³æ¥å®ç°ââè¯¥æ¹æ³åºè¿åä¸ä¸ªå
å«è¦è§å¯ç屿§åç§°çæ°ç»ï¼
static get observedAttributes() {
return ["color", "size"];
}
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