因为每次将自定义元素添加到DOM 中都会调用其类构造函数,所以很容易自动给自定义元素添加
子DOM 内容。虽然不能在构造函数中添加子DOM(会抛出DOMException),但可以为自定义元素添
加影子DOM并将内容添加到这个影子DOM中:
class FooElement extends HTMLElement {
constructor() {
super();
// this 引用Web 组件节点
this.attachShadow({ mode: ‘open’ });
this.shadowRoot.innerHTML = `
I'm inside a custom element!
I'm inside a custom element!
// // 为避免字符串模板和innerHTML 不干净,可以使用HTML 模板和document.createElement() 重构这个例子: //(初始的HTML) // //I'm inside a custom element template!
// const template = document.querySelector('#x-foo-tpl'); class FooElement extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.shadowRoot.appendChild(template.content.cloneNode(true)); } } customElements.define('x-foo', FooElement); document.body.innerHTML += ` // //I'm inside a custom element template!
// // // #shadow-root (open) //I'm inside a custom element template!
// // 这样可以在自定义元素中实现高度的HTML 和代码重用,以及DOM封装。使用这种模式能够自由 创建可重用的组件而不必担心外部CSS 污染组件的样式。 使用自定义元素生命周期方法 可以在自定义元素的不同生命周期执行代码。带有相应名称的自定义元素类的实例方法会在不同生 命周期阶段被调用。自定义元素有以下5 个生命周期方法。 constructor():在创建元素实例或将已有DOM 元素升级为自定义元素时调用。 connectedCallback():在每次将这个自定义元素实例添加到DOM 中时调用。 disconnectedCallback():在每次将这个自定义元素实例从DOM中移除时调用。 attributeChangedCallback():在每次可观察属性的值发生变化时调用。在元素实例初始化 时,初始值的定义也算一次变化。 adoptedCallback():在通过document.adoptNode()将这个自定义元素实例移动到新文档 对象时调用。 下面的例子演示了这些构建、连接和断开连接的回调: 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