主题
自定义元素
Web 组件之一,如果想得到良好兼容,请使用 polymer 库
规范
- 自定义元素名必须至少包含一个不在名称开头和末尾的连字符
- 元素标签不能自关闭
创建自定义元素
- 自定义元素的未来源自类
- 调用
customElements.define()
创建自定义元素
js
class FooElement extends HTMLElement {
constructor() {
super();
console.log('x-foo')
}
}
customElements.define('x-foo', FooElement)
document.body.innerHTML = '<x-foo></x-foo>' // x-foo
可以使用
customElements.get()
方法返回相应自定义元素的类
添加子元素
- 不能再构造函数中添加子 DOM,会报错
- 但可以添影子 DOM
js
class FooElement extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' })
.innerHTML = '<p>hello world</p>'
}
}
customElements.define('x-foo', FooElement)
document.body.innerHTML = '<x-foo></x-foo>'
生命周期
- 可以定义其生命周期
生命周期 | 调用时间 |
---|---|
constructor() | 创建元素实例或将已有 DOM 元素升级为自定义元素时 |
connectedCallback() | 在每次将这个自定义元素实例添加到 DOM 中时 |
disconnectedCallback() | 在每次将这个自定义元素实例从 DOM 中移除时 |
attributeChangedCallback() | 在每次可观察属性的值发生变化时,在元素实例初始化时也算一次 |
adoptedCallback() | 在通过 document.adoptNode() 将这个自定义元素实例移动到新文档对象时 |
js
class FooElement extends HTMLElement {
constructor() {
super()
console.log('ctor')
}
connectedCallback() {
console.log('connected')
}
disconnectedCallback() {
console.log('disconnected')
}
}
customElements.define('x-foo', FooElement)
const fooElement = document.createElement('x-foo') // ctor
document.body.appendChild(fooElement) // connected
document.body.removeChild(fooElement) // disconnected
自定义属性
- 通过设置控制器获取和设置属性
- 还需要设置监听器配合
attributeChangedCallback()
生命周期
js
class FooElement extends HTMLElement {
static get observedAttributes() {
// 返回应该触发 attributeChangedCallback 生命周期的属性
return ['name']
}
get name() {
return this.getAttribute('name')
}
set name(value) {
this.setAttribute('name', value)
}
attributeChangedCallback(key, oldValue, newValue) {
if (oldValue !== newValue) {
this[key] = newValue
}
}
}
customElements.define('x-foo', FooElement)
升级自定义属性
- 可以使用
customElements.whenDefined()
返回一个期约,当相应自定义元素有定义之后解决 - 可以使用
customElements.upgrade()
强制升级