最近忙著用業(yè)余時間搞一個 web 應用開發(fā)框架朗兵,所以搜集資料,今天給大家分享一個 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 工具,可以看出帆焕。
不過我們發(fā)現(xiàn)了我們的 image 不見了惭婿,這是因為什么呢,我想了想通過一個實際的例子給大家解釋一下叶雹,就是我們的 canvas 標簽财饥,在這個標簽里的 p 標簽內容是無法查看。
<canvas>
<p>不顯示</p>
</canvas>
要顯示 image 我們需要在自定義標簽內添加一個 slot 折晦,那么我們就定義一個 slot 標簽钥星,我們先創(chuàng)建一個 template,createElement 接受參數(shù)像 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上后會觸發(fā) connectedCallback 回調函數(shù)宁改,然后在自定義組件添加到后,我們就將模板添加到我們自定義上
我們這個模板的可能被復用魂莫,所以在將模板傳入到 shadowRoot 中時候我們需要復制一個而不是直接使用还蹲。
connectedCallback(){
this.shadowRoot.appendChild(template.content.cloneNode(true))
}
我們通過 querySelector 在 shadowRoot 中查詢到 slot 元素,但是是無法查詢到 image 節(jié)點的耙考。
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 來實現(xiàn)動畫斗遏。
this.animate([
{ transform: 'scale(0)' },
{ transform: 'scale(1)' }
],{
duration:1000
})
沒有效果這是因為我們還差一步,我們給我們自定義組件添加一個樣式鞋邑,這個樣式僅限自定義組件的最頂層的樣式诵次。
template.innerHTML = `<style>:host {display: inline-block }</style><slot />`;
我們給圖片再添加一個旋轉的效果,然后給動畫添加動畫節(jié)奏的參數(shù) easing炫狱。
我們可以動畫添加一個 easing 效果藻懒,怎么解釋 easing 就是將我們動畫節(jié)奏改變一下,可能是先快后慢视译,要理解 bezier 曲線我們需要學習一些數(shù)學知識嬉荆。
this.animate([
{ transform: 'scale(0) rotate(0deg)' },
{ transform: 'scale(1) rotate(1080deg)' }
],{
duration:1000,
easing: 'cubic-bezier(0,0,0.3,1)'
})