vue 实现元素可拖曳

转载的,蛮好用的,多谢原博主​​​​​​​Vue移动端实现元素拖拽 - Tove丶 - 博客园最近遇到一个需求,在App内嵌的H5页面上,有一个悬浮的客服图标,点击可跳转客服页面。最初这个客服图标采用的是固定定位的方式。现在新的需求是,可以拖拽该图标到屏幕任意位置,防止遮挡页面内容。 思考实现https://www.cnblogs.com/chen214/p/15078391.html

 

原博主的方法,会导致拖曳后,页面重新返回顶部,在其基础上,修改了下,加下文

方法封装

/**
 * @name: draggable
 * @description: 元素拖拽
 */
const draggableMixin = {
  data () {
    return {
      // 元素位置,用于样式绑定,动态更新位置(:style="{left: `${x}px`, top: `${y}px`}")
      elePos: {
        x: null,
        y: null
      },
      // 手指(鼠标)触摸点[即拖拽开始的位置]距离拖拽元素左上角的距离
      diffOfTarget: {
        x: 0,
        y: 0
      },
      this.offsetTop:0,
    }
  },
  methods: {
    dragStartHandler (e) {
      let touch = e
      if (e.touches) {
        touch = e.touches[0]
      }
      this.diffOfTarget.x = touch.clientX - e.target.offsetLeft
      this.diffOfTarget.y = touch.clientY - e.target.offsetTop
      // 解决滑动穿透问题
      let scrollTop = document.scrollingElement.scrollTop
      this.offsetTop=scrollTop 
      console.log(scrollTop)
      // todo 在项目的全局样式下,需要定义一个modal-open的样式类
      /**
       * body.modal-open {
       *   position: fixed;
       *   width: 100%;
       *   min-height: 100%;
       * }
       */
      document.body.classList.add('modal-open')
      document.body.style.top = -scrollTop + 'px'
    },
    draggingHandler (e) {
      let touch = e
      if (e.touches) {
        touch = e.touches[0]
      }
      // 设置拖拽元素的位置
      this.elePos.x = touch.clientX - this.diffOfTarget.x
      this.elePos.y = touch.clientY - this.diffOfTarget.y
      // 限制元素不能超过屏幕
      if (this.elePos.x < 0) {
        this.elePos.x = 0
      } else if (this.elePos.x > window.screen.width) {
        this.elePos.x = window.screen.width - e.target.clientWidth
      }
      if (this.elePos.y < 0) {
        this.elePos.y = 0
      } else if (this.elePos.y > window.screen.height) {
        this.elePos.y = window.screen.height - e.target.clientHeight
      }
    },
    dragEndHandler (e) {
      document.body.classList.remove('modal-open')

       //原博主的这句话没加,导致最后拖曳了,会返回到顶部,加上去就没问题了
       document.documentElement.scrollTop=this.offsetTop
    }
  }
}

export default draggableMixin

引用

<template>
  <div>
    <img
      src="../assets/img/customer-service.png"
      alt=""
      class="customer-service"
      :style="{'left': elePos.x + 'px', 'top': elePos.y + 'px' }"
      @mousedown="dragStartHandler"
      @touchstart.stop="dragStartHandler"
      @mousemove="draggingHandler"
      @touchmove.stop="draggingHandler"
      @mouseup="dragEndHandler"
      @touchend.stop="dragEndHandler"
    >
  </div>
</template>

<script>
  import draggableMixin from '@/mixins/draggable'
  export default {
    mixins: [ draggableMixin ]
  }
</script>

<style scoped>
.customer-service {
  position: fixed;
  left: 10px;
  top: 200px;
  width: 36px;
  height: 36px;
  cursor: pointer;
}
</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值