记录一个拖拽组件的代码片段

前言

国内目前的低代码平台,前端部分普遍采取拖拽式完成页面的布局。本次记录一个前端组件的拖拽案例。

Html 5 版

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    *{
      padding: 0px;
      margin: 0px;
    }
    .box{
      width: 300px;
      height: 30px;
      background: pink;
      position: absolute;
      left: 0;
      top: 0;
    }
    .box:hover{
      cursor: move; /** 鼠标悬停 鼠标样式修改 **/
    }
  </style>
</head>
<body>
  <div class="box" id="moveElement">我可以移动</div>
  <script>
    window.onload = function(){
      // 获取元素节点
      let moveElement = document.getElementById('moveElement');
      // 给元素注册鼠标按下事件
      moveElement.onmousedown = function(e){
        //兼容  e || window.event  现在都可以
        let event = e || window.event;  
        // 获取鼠标按下去的那一个点距离边框顶部和左侧的距离
        let point_x=event.offsetX;
        let point_y=event.offsetY;
        //  鼠标移动(小方块在文档上移动,给文档注册一个是移动事件)
        document.onmousemove = function(ent){
          let evt = ent || window.event;
          // 获取鼠标移动的坐标位置
          let ele_left= evt.clientX - point_x;
          let ele_top= evt.clientY - point_y;

          // ----冗余代码---
          // if(ele_left<=0){
          //   // 设置水平方向的最小值
          //   ele_left = 0
          // }else if(ele_left >= window.innerWidth - moveElement.offsetWidth){
          //   // 设置水平方向的最大值
          //   ele_left = window.innerWidth - moveElement.offsetWidth
          // }
          // if(ele_top<=0){
          //   // 设置垂直方向的最小值
          //   ele_top = 0
          // }else if(ele_top >= window.innerHeight - moveElement.offsetHeight){
          //   // 设置垂直方向的最大值
          //   ele_top = window.innerHeight - moveElement.offsetHeight
          // }
          // 优化为下面的
          ele_left = Math.min(Math.max(0,ele_left), window.innerWidth - moveElement.offsetWidth)
          ele_top=  Math.min(Math.max(0,ele_top),  window.innerHeight - moveElement.offsetHeight)
          
          moveElement.style.left = ele_left + 'px';
          moveElement.style.top = ele_top + 'px'
        }

        // 抬起停止移动
        document.onmouseup = function(event){
          console.log("抬起停止移动" )
          // 移除移动和抬起事件
          this.onmouseup = null;
          this.onmousemove = null;
          //修复低版本的ie可能出现的bug
          if(typeof moveElement.releaseCapture!='undefined'){  
            moveElement.releaseCapture();  
          }  
        }
        // 解决有些时候,在鼠标松开的时候,元素仍然可以拖动-使用的是第二种方式
        document.ondragstart = function(ev) {
          ev.preventDefault();
        }
        document.ondragend = function(ev) {
          ev.preventDefault();
        }
      }
    }
  </script>
</body>
</html>

VUE 版

<template>
  <!-- <h1>拖拽式</h1> -->
  <div class="draggable" 
    :style="{top: posY + 'px', left: posX + 'px'}" 
    @click="clickthis"
    @mousedown="start"
    @mousemove="moving"
    @mouseup="stop"
  >可拖拽式 div</div>
</template>
<script>
export default{
  data() {
    return {
      dragging: false,  // 是否正在拖拽
      offsetX: 0,  // 鼠标按下时距离元素左上角的偏移
      offsetY: 0,  // 鼠标按下时距禋元素左上角的偏移
      posX: 0,  // 元素左上角相对于父元素的位置
      posY: 0   // 元素左上角相对于父元素的位置
    };
  },
  methods: {
    clickthis(e){
      console.log("点击事件");
    },
    start(e) {
      console.log("开始拖拽");
      this.dragging = true;
      this.offsetX = e.clientX - this.posX;
      this.offsetY = e.clientY - this.posY;
    },
    moving(e){
      console.log("拖拽移动");
      if (this.dragging) {
        let posX = e.clientX - this.offsetX;
        let posY = e.clientY - this.offsetY;
        if (posX > 0 && posY > 0) {
          this.posX = posX;
          this.posY = posY;
        }
      }
    },
    stop(e){
      console.log("结束拖拽");
      this.dragging = false;
    }
  }
}
</script>
<style scoped>
.draggable {
  position: absolute;
  cursor: move;
  border: 1px solid #ccc;
  padding: 10px;
  background-color: #f0f0f0;
  transition: transform 0.3s;
}

.draggable.dragging {
  transform: scale(1.1);
}
</style>

效果展示

在这里插入图片描述
在这里插入图片描述

核心思想

采取前端页面的鼠标动作onmouseuponmousedownonmousemove,监听按住组件拖拽时,组件的位置变动点,在对应的监听逻辑中,每当位置变更,则获取移动后的定位点,重新设定组件或标签的位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值