<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>
组件定义和使用,js部分
class PopUpInfo extends HTMLElement {
constructor() {
// Always call super first in constructor
super();
// Create a shadow root
const shadow = this.attachShadow({mode: 'open'});
// Create spans
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');
// Take attribute content and put it inside the info span
const text = this.getAttribute('data-text');
info.textContent = text;
// Insert icon
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);
// Create some CSS to apply to the shadow 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;
}
`;
// Attach the created elements to the shadow dom
shadow.appendChild(style);
console.log(style.isConnected);
shadow.appendChild(wrapper);
wrapper.appendChild(icon);
wrapper.appendChild(info);
//外部css的方式,由于不会阻塞渲染,可能会导致一瞬间空白样式
const linkElem = document.createElement('link');
linkElem.setAttribute('rel', 'stylesheet');
linkElem.setAttribute('href', 'style.css');
shadow.appendChild(linkElem);
}
}
// Define the new element
customElements.define('popup-info', PopUpInfo);
;host是整个shadowRoot popup-info的样式
:host()选择包含使用这段 CSS 的Shadow DOM的影子宿主,括号里是父元素的选择器
https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Using_shadow_DOM#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95
//https://github.com/mdn/web-components-examples/tree/master/host-selectors
let style = document.createElement('style');
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.appendChild(style);
style.textContent = 'span:hover { text-decoration: underline; }' +
':host-context(h1) { font-style: italic; }' +
':host-context(h1):after { content: " - no links in headers!" }' +
':host-context(article, aside) { color: gray; }' +
':host(.footer) { color : red; }' +
':host { background: rgba(0,0,0,0.1); padding: 2px 5px; }';
- connectedCallback:当 custom element首次被插入文档DOM时,被调用。
- disconnectedCallback:当 custom element从文档DOM中删除时,被调用。
- adoptedCallback:当 custom element被移动到新的文档时,被调用。
- attributeChangedCallback: 当 custom element增加、删除、修改自身属性时,被调用。
需要注意的是,如果需要在元素属性变化后,触发 attributeChangedCallback()回调函数,你必须监听这个属性。这可以通过定义observedAttributes() get函数来实现,observedAttributes()函数体内包含一个 return语句,返回一个数组,包含了需要监听的属性名称:
static get observedAttributes() {return [‘w’, ‘l’]; }