最近忙着用業餘時間搞一個 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)'
})