移动端盒子拖动效果(有效,坑已踩)(自定义指令)

思路:
1、把要拖动的元素进行相对定位,通过改变定位的px数值来实现拖动效果。
2、通过移动端手指触摸屏幕事件来计算px的值。

实现步骤:

方法一:全局封装
1、建个js文件,将方法封装成vue自定义指令
import Vue from 'vue';
// 1.参数一:指令的名称,定义时指令前面不需要写v-
// 2.参数二:是一个对象,该对象中有相关的操作函数
// 3.在调用的时候必须写v-

const drag = Vue.directive('drag', {
  // 2.每个
  // inserted表示一个元素,插入到DOM中会执行inserted函数,只触发一次,
  // 函数中第一个参数永远是el,表示绑定指令的元素,el参数是原生js对象
  // 注意:通过el.focus()是无法获取焦点的,因为只有插入DOM后才生效
  inserted: function (el) {
    // 1.开会触摸屏幕
    el.ontouchstart = function (e) {
      let disx = e.targetTouches[0].pageX - el.offsetLeft;
      let disy = e.targetTouches[0].pageY - el.offsetTop;
      let maxTop = document.body.clientHeight - el.offsetHeight
      let maxLeft = document.body.clientWidth - el.offsetWidth
      // 2.手指持续移动
      document.ontouchmove = function (e) {
        let left = e.targetTouches[0].pageX - disx
        let top = e.targetTouches[0].pageY - disy
        // 设置上下左右边界
        if (top <= 0) {
          top = 0
        } else if (top > maxTop) {
          top =  `${maxTop}px`
        }else {
          top = `${top}px`
        }
        if (left <= 0) {
          left = 0
        } else if (left > maxLeft) {
          left =  `${maxLeft}px`
        }else {
          left = `${left}px`
        }
        el.style.top = top
        el.style.left = left
      }
      // 3.手指离开屏幕
      document.ontouchend = function (e) {
        // 这里必须要清除,否则点击别的元素也会触发拖动
        document.ontouchmove = document.ontouchend = null;
      }
    }
  }
})
export default drag;
2、在要使用的vue文件内引用封装的js文件,并给要拖动的元素添加自定义指令即可
<template>
  <!-- 拖拽元素 -->
  <div class="goinvoice" >
    <div class="main" v-drag ></div>
  </div>
</template>

<script>
import drag from './drag'

export default {}
</script>

<style>
  .goinvoice {
    width: 100%;
    height: 100%;
    position: fixed;
    left: 0;
    top: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 100;
  }
  .main {
    width: 100px;
    height: 100px;
    background: white;
    position: absolute;
    top: 28%;
    left: 50%;
    z-index: 101;
    padding: 10px;
    border-radius: 2px;
  }
</style>
方法二:组件内封装(可用于有eslint校验的项目)
1、封装
export default {
  directives: {
    drag: {
      inserted: function (el) {
        // 1.开会触摸屏幕
        el.ontouchstart = function (e) {
          let disx = e.targetTouches[0].pageX - el.offsetLeft
          let disy = e.targetTouches[0].pageY - el.offsetTop
          let maxTop = document.body.clientHeight - el.offsetHeight
          let maxLeft = document.body.clientWidth - el.offsetWidth
          // 2.手指持续移动
          document.ontouchmove = function (e) {
            let left = e.targetTouches[0].pageX - disx
            let top = e.targetTouches[0].pageY - disy
            // 设置上下左右边界
            if (top <= 0) {
              top = 0
            } else if (top > maxTop) {
              top = `${maxTop}px`
            } else {
              top = `${top}px`
            }
            if (left <= 0) {
              left = 0
            } else if (left > maxLeft) {
              left = `${maxLeft}px`
            } else {
              left = `${left}px`
            }
            el.style.top = top
            el.style.left = left
          }
          // 3.手指离开屏幕
          document.ontouchend = function (e) {
            // 这里必须要清除,否则点击别的元素也会触发拖动
            document.ontouchmove = document.ontouchend = null
          }
        }
      }
    }
  },
  
}
2、使用
<template>
  <!-- 拖拽元素 -->
  <div class="goinvoice" >
    <div class="main" v-drag ></div>
  </div>
</template>

<style>
  .goinvoice {
    width: 100%;
    height: 100%;
    position: fixed;
    left: 0;
    top: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 100;
  }
  .main {
    width: 100px;
    height: 100px;
    background: white;
    position: absolute;
    top: 28%;
    left: 50%;
    z-index: 101;
    padding: 10px;
    border-radius: 2px;
  }
</style>

注意:
pc端只需要把手指触摸屏幕的三个事件改成鼠标对应的三个事件,pageX 、pageY的获取方式也改一下即可e.pageX

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现同时兼容 PC 端和移动端的元素拖拽功能,可以使用 HTML5 新增的 drag 事件和 touch 事件。 首先,需要将元素设置为可拖拽,可以使用 draggable 属性。例如: ```html <div draggable="true">可拖拽的元素</div> ``` 然后,需要监听元素的 dragstart、drag、dragend 事件或 touchstart、touchmove、touchend 事件来实现拖拽效果。 在 PC 端,可以使用 drag 事件来实现拖拽效果,例如: ```javascript var dragElement = document.getElementById('drag-element'); dragElement.addEventListener('dragstart', function(event) { // 拖拽开始时,保存拖拽元素的 ID event.dataTransfer.setData('text/plain', event.target.id); }); document.body.addEventListener('dragover', function(event) { // 阻止默认拖拽行为 event.preventDefault(); }); document.body.addEventListener('drop', function(event) { // 阻止默认拖拽行为 event.preventDefault(); // 获取拖拽元素的 ID var id = event.dataTransfer.getData('text/plain'); var dragElement = document.getElementById(id); // 将拖拽元素添加到放置区域 event.target.appendChild(dragElement); }); ``` 在移动端,可以使用 touch 事件来实现拖拽效果,例如: ```javascript var dragElement = document.getElementById('drag-element'); var startX, startY; dragElement.addEventListener('touchstart', function(event) { startX = event.touches[0].clientX; startY = event.touches[0].clientY; }); dragElement.addEventListener('touchmove', function(event) { var offsetX = event.touches[0].clientX - startX; var offsetY = event.touches[0].clientY - startY; // 移动元素 this.style.transform = 'translate(' + offsetX + 'px, ' + offsetY + 'px)'; }); dragElement.addEventListener('touchend', function(event) { // 拖拽结束时,清除 transform 样式 this.style.transform = ''; }); ``` 需要注意的是,移动端的 touch 事件可能会和浏览器默认行为冲突,需要使用 preventDefault() 方法来阻止默认行为。另外,由于移动端的屏幕尺寸多样化,需要根据具体情况来调整拖拽的逻辑和样式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值