接下來要講的是如何在vue中實現元素拖動,並且拿到拖動元素相對於父元素的位置偏移量X、Y
下面我們看下頁面的基本結構吧,我們結合圖來介紹這個東西會好理解的多
上面看到了頁面基本結構。container就是我們說的相對父元素,drager就是要被我們拖動的元素,相信這個結構大家都心里有數
接下來,我們使用自定義指令去實現這個功能,這里還不清楚自定義指令內容的同學請看官網 : https://cn.vuejs.org/v2/guide/custom-directive.html
官網對自定義指令的實現以及生命周期說的很清楚了
下面我們想一個問題,怎么拿到drager元素相對於父元素的偏移量?這個問題如果解決了,那就OK了。
為了解決這個問題,也是想了很多,下面請看我畫的圖
這里我們要清楚一點。那就是我們每次在不同的位置點擊拖拽元素的時候,點擊的坐標都是新的,我們從鼠標 按下-->拖動->松開 是一個完整的過程,每一次都是新的一個完整過程。
接下來請仔細看下面兩個代碼
oDiv.onmousedown = function (e) { // 鼠標按下,計算當前元素距離可視區的距離 let disX = e.clientX - oDiv.offsetLeft --------------------------------------------------------- document.onmousemove = function (e) { let l = e.clientX - disX
當鼠標按下的時候,我們用鼠標觸發事件的坐標(對於body/可視區域) - 拖拽元素距離container(父級元素)的距離 S1
再看第二段代碼:當鼠標在按住后發生推拽時觸發的事件-> 拖動鼠標時鼠標的clientX - S1,你們可以畫圖或者腦補,就會發現這個差值就是推拽元素相對父級元素拖拽后的距離!
弄懂這點就好辦了。下面看我們直接看代碼
Vue.directive('drag', { inserted (el, binding) { let oDiv = el
// 左邊距最大值 let maxLeft = el.parentNode.clientWidth - el.clientWidth
// 上邊距最大值 let maxTop = el.parentNode.clientHeight - el.clientHeight oDiv.onmousedown = function (e) { // 鼠標按下,計算當前元素距離可視區的距離 let disX = e.clientX - oDiv.offsetLeft let disY = e.clientY - oDiv.offsetTop document.onmousemove = function (e) {
// 獲取到鼠標拖拽后的橫向位移(距離父級元素) let l = e.clientX - disX
// 獲取到鼠標拖拽后的縱向位移(距離父級元素)
let t = e.clientY - disY
oDiv.style.left = l + 'px'
oDiv.style.top = t + 'px'
if (e.clientX - disX <= 0) { oDiv.style.left = 0 + 'px' }
if (e.clientY - disY <= 0) { oDiv.style.top = 0 + 'px' }
if (e.clientX - disX >= maxLeft) { oDiv.style.left = maxLeft + 'px' }
if (e.clientY - disY >= maxTop) { oDiv.style.top = maxTop + 'px' }
// 將此時的位置傳出去
binding.value({x: oDiv.style.left, y: oDiv.style.top}) }
// 松開事件后,移除事件
document.onmouseup = function (e) { document.onmousemove = null document.onmouseup = null }
}
}
})
------------------------------------------------------------------------------------------------------
<div v-drag="greet"></div>
// 我們可以在函數中拿到指令傳出來的數據對象
greet(obj){
console.log(obj)
}
這是我的個人筆記,希望對你有幫助。