Web Components是一套不同的技术,允许您创建可重用的定制元素(它们的功能封装在您的代码之外)并且在您的web应用中使用它们。
web component主要由四项主要技术组成:custome element、shadow DOM、HTML template、HTML imports,可参考MDN。
一、customElements
示例
customeElements.define('my-element', MyElement, {extends: 'p'})
这个元素叫做my-element,它的类对象是MyElement, 继承自**
**元素,类对象使用es2015的写法如下
class MyElement extends HTMLElement {
constructor() {
super();
const showRoot = this.attachShadow({mode: 'open'});
const container = document.createElement('span');
const text = this.getAttribute('text');
container.innerHTML = text;
showRoot.appendChild(container);
}
}
customElements.define('my-element', MyElement);
上面这种方式不继承任何其他内建的元素,称为独立元素。使用方式为 或document.createElement(‘my-element’), 代码地址
另一种元素称为customized built-in元素,继承与某个特定的内建元素,所以拥有它的所有特征。
class MyList extends HTMLUListElement {
constructor() {
super();
const lis = document.querySelectorAll(':root li');
Array.from(lis).forEach(li => {
li.textContent = `你好, ${li.textContent}`;
});
}
}
customElements.define('my-list', MyList, {extends:'ul'});
使用方式,
<ul is="my-list">
<li>china</li>
<li>USA</li>
</ul>
生命周期
- connectedCallback: 元素首次被插入文档调用
- disconnectedCallback:元素从文档中被移除调用
- adoptedCallback: 自定义元素被移动到新的文档中时调用
- attributeChangedCallback: 元素属性发生变化时调用
下面的示例会在自定义被元素插入文档后画一个红色的矩形,然后修改自定义元素的with、height,矩形框会变化。
class MyLifecycle extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({mode: 'open'});
const div = document.createElement('div');
const style = document.createElement('style');
shadow.appendChild(style);
shadow.appendChild(div);
}
// 要监听属性的变化,必须通过observedAttributes监听这个属性
static get observedAttributes() {
return ['width', 'height'];
}
//属性变化的回调函数
attributeChangedCallback() {
console.log('attributeChangedCallback')
udpateStyle(this);
}
connectedCallback() {
console.log('connectedCallback');
udpateStyle(this);
}
disconnectedCallback() {
console.log('distconnectedCallback')
}
}
customElements.define('my-lifecycle', MyLifecycle);
/**
* 设置样式
* @param {*} elem
*/
function udpateStyle(elem) {
const shadow = elem.shadowRoot;
const childNodes = shadow.childNodes;
Array.from(childNodes).forEach(child => {
if (child.nodeName === 'STYLE') {
child.textContent = 'div {'
+ "width:" + elem.getAttribute('width') + 'px;'
+ "height:" + elem.getAttribute('height') + 'px;'
+ "background-color:" + elem.getAttribute('color') + ';'
+ '}'
}
})
}
function changeAttributes() {
const node = document.querySelector('my-lifecycle');
node.setAttribute('width', parseInt(node.getAttribute('width')) + 10);
node.setAttribute('height', parseInt(node.getAttribute('height')) + 10);
}
以上只是简单的介绍了自定义元素的创建。后面补充shadow DOM、template