vue中跟随鼠标移动和边界处理

需求:需要能够拖拽图片进行移动,不会超出容器边界范围

 1.获取到鼠标移动的坐标和被点击拖拽的dom的坐标

补充前端跟坐标有关的知识点

1.pageX和pageY是整个文档开始计算的坐标, 红色表示pageX和pageY

2.offsetX和offsetY是一个鼠标在一个元素内的坐标, 蓝色表示offsetX和offsetY

3.clientX和clientY是当前屏幕可视化局域计算的坐标, 当文档不向下滚动时,红色也可以表示clientX和clientY

分析得出:当前图片已经超出可视化区域,需要使用pageX和pageY才能准确地拿到鼠标坐标

2.通过计算可以获取到当前图片左距离和上距离

这里拖拽采用的事件是:

mousedown:鼠标点击时触发

mousemove:鼠标移动时触发

mouseup:鼠标松开时触发

其中mousedown应该绑定被拖拽的元素,而mouseup就所谓了,mousemove一般通过document或者window进行监听,当然也可以是父容器。

在vue2的图片中绑定@mouseup="mouseup" @mousedown="dragImg"

dragImg(img) {
      img.preventDefault()
      this.imgObj = img
      window.addEventListener('mousemove', this.move)
}

mouseup() {
      window.removeEventListener('mousemove', this.move)
      this.getContainerH()
}
​
this.imgObj.target.style.position = 'absolute'
this.imgObj.target.style.left = pageX - this.imgObj.offsetX + 'px'
this.imgObj.target.style.top = pageY - this.imgObj.offsetY + 'px'

​

3.进行边界判断以及父容器高度处理

 首先是最简单的上边界和左边界判断:

//边界判断
if (this.imgObj.target.offsetTop <= 0) {
   this.imgObj.target.style.top = 0 + 'px'
}

if (this.imgObj.target.offsetLeft <= 0) {
   this.imgObj.target.style.left = 0 + 'px'
}

然后是右边界判断:

这里需要获取到屏幕的内在宽度,一般都作为一个工具函数,这里是通用的写法,如下代码所示:

function getClientW() {
  return {
    width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
    height:
      window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
  }
}

 通过当前元素的做距离加上当前元素的自身大小和屏幕内在宽度进行比较处理可得如下代码:

   if (
        +this.imgObj.target.style.left.split('px')[0] + this.imgObj.target.clientWidth >=
        this.client.width
      ) {
        this.imgObj.target.style.left = this.client.width - this.imgObj.target.clientWidth + 'px'
      }

最后的问题是下边界无需处理,由于元素已经脱离了标准流,会导致父元素高度塌陷,为了能够显示父元素高度以此来添加背景颜色,这里需要用给父容器实时获取最新高度。

  getContainerH() {
      const singleMvIndex = this.$refs.singleMvIndex
      singleMvIndex.style.height =
        this.imgObj.target.clientHeight + this.imgObj.target.offsetTop + this.paddingH + 'px'
      if (singleMvIndex.clientHeight < this.client.height) {
        singleMvIndex.style.height = this.client.height + 'px'
      }
    },

这里用此函数在拖拽时不断调用,singleMvIndex是容器的dom,

容器高度 = 元素内在高度 + 元素距离父容器顶端距离 + 容器自带padding

容器就会不断变大,向上拖拽时容器该需要变小,

这里的做法时容器高度如果小于屏幕内在高度就会等于屏幕内在高度就解决问题了。

这里算是对一些小的问题的解决,算是分享给大家,希望能帮助到一些人,谢谢。

最后时mousemove整体代码:

 move(e) {
      let { pageX, pageY } = e
      this.imgObj.target.style.position = 'absolute'
      this.imgObj.target.style.left = pageX - this.imgObj.offsetX + 'px'
      this.imgObj.target.style.top = pageY - this.imgObj.offsetY + 'px'
      //边界判断
      if (this.imgObj.target.offsetTop <= 0) {
        this.imgObj.target.style.top = 0 + 'px'
      }
      if (this.imgObj.target.offsetLeft <= 0) {
        this.imgObj.target.style.left = 0 + 'px'
      }
      if (
        +this.imgObj.target.style.left.split('px')[0] + this.imgObj.target.clientWidth >=
        this.client.width
      ) {
        this.imgObj.target.style.left = this.client.width - this.imgObj.target.clientWidth + 'px'
      }
      this.getContainerH()
    },

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值