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

 这是我的个人笔记,希望对你有帮助。

posted on 2017-11-30 10:46  维尼-winnie  阅读(2795)  评论(0编辑  收藏  举报