微信的浮窗,大伙應該都用過,當我們正在閱讀一篇公眾號文章時,突然需要處理微信消息,點擊浮窗,在微信上會有個浮標,點擊浮標可以再次回到文章。
我們今天打算擼一個類似微信的浮標組件,我們期望組件有以下功能
支持拖拽 支持左右吸附 支持頁面上下滑動時隱藏效果預覽
拖拽事件
浮標的核心功能的就是拖拽,對鼠標或移動端的觸摸的事件來說,有三個階段,鼠標或手指接觸到元素時,鼠標或手指在移動的過程,鼠標或手指離開元素。這個三個階段對應的事件名稱如下:
mouse: { start: 'mousedown', move: 'mousemove', stop: 'mouseup'},touch: { start: 'touchstart', move: 'touchmove', stop: 'touchend'}元素定位
滑動容器我們采用絕對定位,通過設置 top 和 left 屬性來改變元素的位置,那我們怎么獲取到新的 top 和 left 呢?
我們先看下面這張圖
黃色區域是拖拽的元素,藍色的點就是鼠標或手指觸摸的位置,在元素移動的過程中,這些值也會隨著發生改變,那么我們只要計算出新的觸摸位置和最初觸摸位置的橫坐標和豎坐標的變化,就可以算出移動后的 top left ,因為拖拽的元素不隨著頁面滾動而變化,所以我們采用 pageX pageY 這兩個值。用公式簡單描述就是;
newTop = initTop + (currentPageY - initPageY)newLeft = initLeft + (currentPageX - initPageX)
拖拽區域
拖拽區域默認是在拖拽元素的父級元素內,所以我們需要計算出父級元素的寬高。這里有一點需要注意,如果父級的寬高是由異步事件來改變的,那么獲取的時候就會不準確,這種情況就需要改變下布局。
private getParentSize() { const style = window.getComputedStyle( this.$el.parentNode as Element, null ); return [ parseInt(style.getPropertyValue('width'), 10), parseInt(style.getPropertyValue('height'), 10) ];}拖拽的前中后
有了上面的基礎,我們分析下拖拽的三個階段我們需要做哪些工作
觸摸元素,即開始拖拽,將當前元素的 top left 和觸摸點的 pageX pageY 用對象存儲起來,然后監聽移動和結束事件左右吸附
在手指離開后,若元素偏向某一側,便吸附在該側的邊上,那么在拖拽事件結束后,根據元素的X軸中心的與父級元素的X軸中心點做比較,就可知道往左還是往右移動
新聞熱點
疑難解答