移动端页面中拖拽的实现以及自定义指令拖拽的实现

这篇博客介绍了如何在移动端实现元素的自定义拖拽功能,包括点击事件处理、拖拽过程中的边界限制以及释放后的操作。代码示例展示了在Vue中使用自定义指令v-drag来实现拖拽,并提供了相应的CSS样式以确保元素在屏幕右下角的布局。此外,还讨论了如何在main.js中全局注册并使用该自定义指令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先进性布局,一个背景色为蓝色的邮件圆形图标在屏幕右下角位置

<div
  class="Customer"
  id="default_drag_comp"
  @click="goNext" //跳转页面
  @touchstart="down" //鼠标按下触发事件
  @touchmove="move" //鼠标移动触发事件
  @touchend="end" //松开鼠标触发事件
>
  <i class="iconfont icon-xin"></i>
</div>

<script>
export default {
  data() {
    return {
    > 在 data 里定义
      flags: false, //是否开启拖拽
      position: { x: 0, y: 0 },
      nx: "", //鼠标移动X
      ny: "", //鼠标移动Y
      dx: "", //鼠标按下X轴
      dy: "", //鼠标按下Y轴
      maxW: 0, //可视窗口宽
      maxH: 0, //可是窗口高
    };
  },

> 在 mounted 里获取到屏幕宽高赋值

  mounted() {
    document.body.style.background = "#f2f3f5";
    this.maxW = document.documentElement.clientWidth; //获取可视窗口宽
    this.maxH = document.documentElement.clientHeight; //获取可视窗口高
  },
  

> 实现功能

  methods: {
    // 点击实现页面跳转
    goNext() {
      //this.$router.push("/custmoer");
      // this.$emit("goNext");
    },
    // 实现移动端拖拽
    down() {
      console.log(event);
      this.flags = true; //鼠标按下开启拖拽
      var touch;
      if (event.touches) {
        touch = event.touches[0]; //通过event.touches[0]拿到鼠标按下的数据
      }
      this.dx = touch.clientX; //将鼠标按下的X轴数据存储data
      // console.log(this.dx);
      this.dy = touch.clientY; //将鼠标按下的Y轴数据存储data
    },
    move(event) {
      event.preventDefault(); //方法阻止元素发生默认的行为。
      //querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素
      let default_drag_comp = document.querySelector("#default_drag_comp");
      if (this.flags) {
        //判断用户是否在拖拽  如果拖拽
        var touch;
        if (event.touches) {
          touch = event.touches[0]; //将拖拽的数据赋值给touch
        }
        this.nx = touch.clientX - this.position.x;
        this.ny = touch.clientY - this.position.y;
        //左右范围
        //console.log(this.nx,this.ny)
        if (this.nx < 0) {
          //设置拖动范围   不可以拖动到可是窗口外 当拖动X轴小于0时说明已经拖出去了  就将X轴赋值为0
          this.nx = 0;
        } else if (this.nx > this.maxW) {
          //如果大于可视窗口宽时将可视窗口宽赋值给X轴
          this.nx = this.maxW;
        }
        //上下范围
        if (this.ny < 0) {
          //设置拖动范围   不可以拖动到可是窗口外 当拖动X轴小于0时说明已经拖出去了  就将Y轴赋值为0
          this.ny = 0;
        } else if (this.ny >= this.maxH) {
          //如果大于可视窗口高时将可视窗口宽赋值给X轴
          this.ny = this.maxH;
        }
        default_drag_comp.style.left = this.nx - 30 + "px"; //将拖拽的X轴赋值给div
        default_drag_comp.style.top = this.ny - 30 + "px"; //将拖拽的Y轴赋值给div
        //阻止页面的滑动默认事件;如果碰到滑动问题,1.2 请注意是否获取到 touchmove
        // document.addEventListener(
        //   "touchmove",
        //   function () {
        //     // event.preventDefault();
        //   },
        //   false
        // );
      }
    },
    //鼠标释放时候的函数
    end() {
      this.flags = false; //鼠标释放关闭拖拽
    },
  },
};
</script>



calss样式:
<style lang="scss">
  .iconfont {
    font-size: 30px;
  }
  .Customer {
      height: 60px;
      width: 60px;
      line-height: 60px;
      border-radius: 100%;
      background: #007aff;
      text-align: center;
      color: #fff;
      position: fixed;
      bottom: 80px;
      right: 10px;
      z-index: 10;
  }
</style>

自定义拖拽的实现

main.js中全局引入自定义注册指令

 import  vDrag from "@/directive/drag"
 Vue.directive("drag",vDrag)

src下创建directive目录,在directive目录下创建drag.js

/**
 * @description 移动端拖拽指令
 * @author  xl
 * @date 2022-6-8 09:53
 * 
 */
export  default {
    inserted(el){
        let switchPos = {
            x: 0,
            y: 0,
            startX: 0,
            startY: 0,
            endX: 0,
            endY: 0
        }
        el.addEventListener("touchstart",function (e) {
            // console.log(e);
            switchPos.startX  = e.touches[0].pageX;
            switchPos.startY  = e.touches[0].pageY;
        })
        el.addEventListener("touchend",function (e) {
            // console.log(e);
            switchPos.x = switchPos.endX;
            switchPos.y = switchPos.endY;
            switchPos.startX = 0;
            switchPos.startY = 0;
        })
        el.addEventListener("touchmove",function (e) {
            // console.log(e);
            if (e.touches.length>0) {
                let offsetX = e.touches[0].pageX - switchPos.startX;
                let offsetY = e.touches[0].pageY - switchPos.startY;

                let x = switchPos.x - offsetX;
                let y = switchPos.y - offsetY;
        
                // 限制拖拽范围  
                if (x+el.offsetWidth > document.documentElement.offsetWidth) {
                    x = document.documentElement.offsetWidth - el.offsetWidth
                }
                if (y+el.offsetHeight > document.documentElement.offsetHeight) {
                    y = document.documentElement.offsetHeight - el.offsetHeight
                }

                if(x<0){
                    x =0
                }
                if(y<0){
                    y =0
                }

                el.style.right = x +"px";
                el.style.bottom = y +"px";
                switchPos.endX = x 
                switchPos.endY = y
                
                // 阻止默认事件
                e.preventDefault()

            }

        })
    }
}

需要使用拖拽指令地方使用自定义指令 v-drag 然后进行布局 (在app.vue中)

<div  class="custom" v-drag>
    <i class="iconfont icon-lianxi"></i>
</div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值