无依赖自定义组件的实践
Wscats opened this issue · comments
enoyao commented
组件
无依赖自定义组件的实践需要依赖三个技术(浏览器原生就支持组件化)
- Custom elements(自定义元素)
customElements.define('my-header', Xheader)
- Shadow DOM(影子DOM)
attachShadow
- HTML templates(HTML模板)
<template>和 <slot>
// HTML模板技术包含两个标签:<template>和 <slot>
// 当需要在页面上重复使用同一个 DOM结构时,可以用 template 标签来包裹它们,然后进行复用
// slot标签让模板更加灵活,使得用户可以自定义模板中的某些内容
const str =
`
<style>
header {
height: 50px;
line-height: 50px;
width: 100%;
text-align: center;
color: white;
background-color: red;
}
</style>
<header><slot name="my-title">头部</slot></header>
`
class Xheader extends HTMLElement {
constructor() {
super();
const template = document.createElement('template');
template.innerHTML = str;
const templateContent = template.content;
// 创建一颗可见的DOM树,这棵树会附着到某个DOM元素上
// 这棵树的根节点称之为shadow root,只有通过shadow root 才可以访问内部的shadow dom,并且外部的css样式也不会影响到shadow dom上
// 相当于创建了一个独立的作用域
this.attachShadow({
mode: 'open'// 'open' 表示该shadow dom可以通过js 的函数进行访问
}).appendChild(
templateContent.cloneNode(true)// 操作shadow dom
);
}
}
// 允许自定义元素及其行为,然后可以在您的用户界面中按照需要使用它们
customElements.define('my-header', Xheader);
事件绑定
经过测试,发现需要在appendChild()
之后,才能绑定事件
attachShadow.appendChild(
templateContent.cloneNode(true) // 操作shadow dom
);
// 编译模板,要在appendChild之后
attachShadow.querySelector(xxx);
let nodes = attachShadow.childNodes;