vue實(shí)現(xiàn)拖動(dòng)效果

用于實(shí)現(xiàn)一些懸浮在右下角的可拖動(dòng)的全局按鈕

<template>
<div>
  <button ref="content" class="btn">一個(gè)按鈕</button>
  <Modal v-model="modal" ></Modal>
</div>
</template>

<script>
export default {
  data () {
    return {
      modal: false
    }
  },
  mounted () {
    draggable(this.$refs.content.$el, this.showModal)
  },
  methods: {
    showModal () {
      this.modal = true
    },
    /**
     * @param {drag} element 需要移動(dòng)的元素
     * @param {fun} function 點(diǎn)擊觸發(fā)的事件
     */
    draggable (drag, fun) {
      var startEvt, moveEvt, endEvt
      // 判斷是否支持觸摸事件
      if ('ontouchstart' in window) {
        startEvt = 'touchstart'
        moveEvt = 'touchmove'
        endEvt = 'touchend'
      } else {
        startEvt = 'mousedown'
        moveEvt = 'mousemove'
        endEvt = 'mouseup'
      }
      drag.style.cursor = 'grab'
      var disX, disY, left, top, starX, starY, oLeft, oTop
      drag.addEventListener(startEvt, startFun)

      function startFun (event) {
        // 阻止頁(yè)面的滾動(dòng),縮放
        event.preventDefault()
        // 兼容IE瀏覽器
        drag.style.cursor = 'grabbing'
        var e = event || window.event
        oLeft = drag.offsetLeft
        oTop = drag.offsetTop
        // 手指按下時(shí)的坐標(biāo)
        starX = e.touches ? e.touches[0].clientX : e.clientX
        starY = e.touches ? e.touches[0].clientY : e.clientY
        // 手指相對(duì)于拖動(dòng)元素左上角的位置
        disX = starX - drag.offsetLeft
        disY = starY - drag.offsetTop
        // 按下之后才監(jiān)聽后續(xù)事件
        document.addEventListener(moveEvt, moveFun)
        document.addEventListener(endEvt, endFun)
      }

      function moveFun (event) {
        // 兼容IE瀏覽器
        var e = event || window.event
        left = (e.touches ? e.touches[0].clientX : e.clientX) - disX
        top = (e.touches ? e.touches[0].clientY : e.clientY) - disY
        // 限制拖拽的X范圍,不能拖出屏幕
        if (left < 0) {
          left = 0
        } else if (left > document.documentElement.clientWidth - drag.offsetWidth) {
          left = document.documentElement.clientWidth - drag.offsetWidth
        }
        // 限制拖拽的Y范圍,不能拖出屏幕
        if (top < 0) {
          top = 0
        } else if (top > window.innerHeight - drag.offsetHeight) {
          top = window.innerHeight - drag.offsetHeight
        }
        drag.style.left = left + 'px'
        drag.style.top = top + 'px'
      }

      function endFun (event) {
        drag.style.cursor = ''
        document.removeEventListener(moveEvt, moveFun)
        document.removeEventListener(endEvt, endFun)
        if (oLeft == drag.offsetLeft && oTop == drag.offsetTop && fun) { // 點(diǎn)擊
          fun()
        }
      }
    }

  }
}
</script>

<style scoped>
.btn{
  position: fixed;
  height: 60px;
  bottom: 120px;
  right: 80px;
  text-align: center;
  /* transition: all 0.08s; */
  user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -webkit-user-select: none;
  z-index: 997;
}
</style>


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容