美文网首页Vue 组件库
Vue 可拖拽的组件

Vue 可拖拽的组件

作者: 阿畅_ | 来源:发表于2021-10-26 15:56 被阅读0次

好久没更新了,最近写了一个小的拖拽组件,分享一下
场景:h5项目上要有一个联系客服或查看相关问题的模块,一般定位在页面的左侧或右侧,可当页面滑动时,可能会遮罩页面内容,所有就做成可拖拽的。

写起来很简单,使用 touchstart touchmove touchend 三个时间

  • touchstart: 主要做一些例如 禁止滚动,防止滚动冲突
  • touchmove: 当手指滚动时,使目标元素(也就是组件)跟随手指的滚动进行移动
  • touchend: 用于手指移开,判断组件是回到左边还是右边。

我里的组件 props isOnlyLeft 意思是:只能在屏幕的左半边移动,isOnlyRight 只在屏幕右半边移动

<template>
    <div ref="drawable"
        :style="{left: left, top: top}"
        class="draggable-box"
        @touchstart="touchstart"
        @touchend="touchend"
        @touchmove="mousemove">
        <slot />
    </div>
</template>
<script>
export default {
  name: 'DrawableBox',
  props: {
    top: String,
    left: String,
    isOnlyLeft: Boolean,
    isOnlyRight: Boolean
  },
  data () {
    return {
      flag: false
    }
  },
  methods: {
    touchstart () {
      this.flag = true
      // 禁用页面滚动条
      document.getElementById('app').style = 'overflow: hidden;'
      this.$refs.drawable.style.transition = 'none'
    },
    touchend () {
      this.flag = false
      this.$refs.drawable.style.transition = 'all 0.2s'
      document.getElementById('app').style = 'overflow: auto;'
      let left = this.$refs.drawable.offsetLeft
      let screenWidth = window.screen.width
      let oWidth = this.$refs.drawable.offsetWidth
      // 判断是回到左边还是右边
      if (left + oWidth / 2 <= screenWidth / 2) {
        this.$refs.drawable.style.left = '0px'
      } else {
        this.$refs.drawable.style.left = screenWidth - oWidth + 'px'
      }
    },
    mousemove (e) {
      // 禁止默认行为,防止在微信上打开和下拉冲突
      e.preventDefault()
      if (this.flag) {
        let clientY = e.targetTouches[0].clientY
        let clientX = e.targetTouches[0].clientX
        let offsetHeight = this.$refs.drawable.offsetHeight
        let offsetWidth = this.$refs.drawable.offsetWidth
        let top = clientY - offsetHeight / 2
        let left = clientX - offsetWidth / 2
        // 屏幕得宽度
        let screenWidth = window.screen.width
        let screenHeight = window.screen.height
        let maxTop = screenHeight - offsetHeight
        let maxLeft = 0
        const halfWidth = screenWidth / 2
        if (this.isOnlyLeft) {
          maxLeft = halfWidth - offsetWidth / 2
        } else {
          maxLeft = screenWidth - offsetWidth
        }
        if (top <= 0) {
          top = 0
        }
        if (top > maxTop) {
          top = maxTop
        }
        if (this.isOnlyRight) {
          if (left <= halfWidth) {
            left = halfWidth
          }
        } else {
          if (left <= 0) {
            left = 0
          }
        }

        left = left > maxLeft ? maxLeft : left

        this.$refs.drawable.style.top = top + 'px'
        this.$refs.drawable.style.left = left + 'px'
      }
    }
  }
}
</script>
<style lang="stylus" scoped>
.draggable-box
  position: fixed
  z-index: 100
</style>

相关文章

网友评论

    本文标题:Vue 可拖拽的组件

    本文链接:https://www.haomeiwen.com/subject/itcyaltx.html