首页 > 技术文章 > vue 拖拽移动(类似于iPhone虚拟home )

richard1015 2018-09-07 15:42 原文

vue 移动端 PC 兼容 元素 拖拽移动 

效果演示

 

事件知识点

移动端 PC端 注释
touchstart mousedown 鼠标/手指按下事件
touchmove mousemove 鼠标/手指移动事件
touchend mouseup 鼠标松开/手指抬起事件

 

实现思路
1.鼠标按下时  记录 按下状态  记录x y轴坐标
2.按下移动时 动态计算坐标 设置拖拽元素 style 控制位置 ;
2.1判断拖拽区域 溢出时 归位判断;
2.2拖拽时 阻止页面滑动
3.鼠标抬起  修改 按下状态 
 
上代码
<template lang="pug">
    //- 当前页面全局容器
    div.SchemeDetail(
        ref='pageDiv'
        @mousemove="onmousemove($event)" @touchmove="onmousemove($event)"
        @mouseup="onmouseup($event)" @touchend="onmouseup($event)"
    )
      //- 加号拖拽元素   
      div.action-mgr(:class="{ active :mgrState}"
      ref='actionMgr'
      @click="mgrState=!mgrState"
      @mousedown="onmousedown($event)" @touchstart="onmousedown($event)")
        <i class="icon iconfont icon-jia"></i>
   .....
</template>

<script>
export default {
  data() {
    return {
      mgrState: false,
      mousedownState: false, //鼠标默认抬起
      iX: 0,//鼠标坐标 与 拖拽按钮 间距 x
      iY: 0//鼠标坐标 与 拖拽按钮 间距 y
    };
  },
  methods: {
    send() {
      console.log("send");
    },
    edit() {
      console.log("edit");
    },
    /* 鼠标按下事件 */
    onmousedown(event) {
      /* 此处判断  pc 或 移动端 得到 event 事件 */
      var touch;
      if (event.touches) {
        touch = event.touches[0];
      } else {
        touch = event;
      }
      // 鼠标点击 面向页面 的 x坐标 y坐标
      let { clientX, clientY } = touch;
      // 鼠标x坐标 - 拖拽按钮x坐标  得到鼠标 距离 拖拽按钮 的间距
      this.iX = clientX - this.$refs.actionMgr.offsetLeft;
      // 鼠标y坐标 - 拖拽按钮y坐标  得到鼠标 距离 拖拽按钮 的间距
      this.iY = clientY - this.$refs.actionMgr.offsetTop;
      // 设置当前 状态为 鼠标按下
      this.mousedownState = true;
    },
    /* 鼠标移动事件 */
    onmousemove(event) {
      //鼠标按下 切移动中
      if (this.mousedownState) {
        /* 此处判断  pc 或 移动端 得到 event 事件 */
        var touch;
        if (event.touches) {
          touch = event.touches[0];
        } else {
          touch = event;
        }
        // 鼠标移动时 面向页面 的 x坐标 y坐标
        let { clientX, clientY } = touch;
        //当前页面全局容器 dom 元素  获取容器 宽高
        let {
          clientHeight: pageDivY,
          clientWidth: pageDivX
        } = this.$refs.pageDiv;
        /* 鼠标坐标 - 鼠标与拖拽按钮的 间距坐标  得到 拖拽按钮的 左上角 x轴y轴坐标 */
        let [x, y] = [clientX - this.iX, clientY - this.iY];

        //拖拽按钮 dom 元素  获取 宽高 style 对象
        let {
          clientHeight: actionMgrY,
          clientWidth: actionMgrX,
          style: actionMgrStyle
        } = this.$refs.actionMgr;
        /* 此处判断 拖拽按钮 如果超出 屏幕宽高 或者 小于  
           设置 屏幕最大 x=全局容器x y=全局容器y 否则 设置 为 x=0 y=0 
        */
        if (x > pageDivX - actionMgrX) x = pageDivX - actionMgrX;
        else if (x < 0) x = 0;
        if (y > pageDivY - actionMgrY) y = pageDivY - actionMgrY;
        else if (y < 0) y = 0;
        // 计算后坐标  设置 按钮位置
        actionMgrStyle.left = `${x}px`;
        actionMgrStyle.top = `${y}px`;
        actionMgrStyle.bottom = "auto";
        actionMgrStyle.right = "auto";
        //当按下键滑动时, 阻止屏幕滑动事件
        event.preventDefault();
      }
    },
    /* 鼠标抬起事件 */
    onmouseup(event) {
      // 设置当前状态为鼠标抬起
      this.mousedownState = false;
    }
  }
};
</script>

 

 

推荐阅读