最近忙着用业余时间搞一个 web 应用开发框架,所以搜集资料,今天给大家分享一个 web component。
<zi-logo>
<img src="zidealogo.jpg"/>
</zi-logo>
<script>
class ZiLogo extends HTMLElement{
constructor(){
super();
console.log("hello from logo")
}
}
customElements.define('zi-logo',ZiLogo)
</script>
showRoot
showRoot 会给我们提供一个封闭不收干扰空间,想一想我们没有模块没有作用域 css 吧,有了 showRoot 了我们就相当于为 css 做了一个作用域,可以说我们的地盘我做主。
我们可以打开 chrome 的 dev 工具,可以看出。
不过我们发现了我们的 image 不见了,这是因为什么呢,我想了想通过一个实际的例子给大家解释一下,就是我们的 canvas 标签,在这个标签里的 p 标签内容是无法查看。
<canvas>
<p>不显示</p>
</canvas>
要显示 image 我们需要在自定义标签内添加一个 slot ,那么我们就定义一个 slot 标签,我们先创建一个 template,createElement 接受参数像 div、p 和 template 了。还有 attachShadow 接受一个对象,其中 mode 赋值为 open。
const template = document.createElement('template');
template.innerHTML = "<slot />";
class ZiLogo extends HTMLElement{
constructor(){
super();
console.log("hello from logo")
this.attachShadow({
mode:'open',
})
}
}
当组件添加到body上后会触发 connectedCallback 回调函数,然后在自定义组件添加到后,我们就将模板添加到我们自定义上
我们这个模板的可能被复用,所以在将模板传入到 shadowRoot 中时候我们需要复制一个而不是直接使用。
connectedCallback(){
this.shadowRoot.appendChild(template.content.cloneNode(true))
}
我们通过 querySelector 在 shadowRoot 中查询到 slot 元素,但是是无法查询到 image 节点的。
connectedCallback(){
this.shadowRoot.appendChild(template.content.cloneNode(true))
const slot = this.shadowRoot.querySelector('slot');
console.log(slot)
const img = slot.querySelector('img');
console.log(img) // null
}
我们想给 image 添加动画,也不必直接给 image 添加动画,我们可以给我们组件添加一个动画,那么就调用 this.animate 来实现动画。
this.animate([
{ transform: 'scale(0)' },
{ transform: 'scale(1)' }
],{
duration:1000
})
没有效果这是因为我们还差一步,我们给我们自定义组件添加一个样式,这个样式仅限自定义组件的最顶层的样式。
template.innerHTML = `<style>:host {display: inline-block }</style><slot />`;
我们给图片再添加一个旋转的效果,然后给动画添加动画节奏的参数 easing。
我们可以动画添加一个 easing 效果,怎么解释 easing 就是将我们动画节奏改变一下,可能是先快后慢,要理解 bezier 曲线我们需要学习一些数学知识。
this.animate([
{ transform: 'scale(0) rotate(0deg)' },
{ transform: 'scale(1) rotate(1080deg)' }
],{
duration:1000,
easing: 'cubic-bezier(0,0,0.3,1)'
})