關於用自定義指令在vue中實現元素拖動


接下來要講的是如何在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)
}

 這是我的個人筆記,希望對你有幫助。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM