vue项目中图标可拖拽功能实现

本文介绍如何在Vue项目中实现图标拖拽功能。通过监听鼠标事件,获取鼠标坐标并转换为图标的位置,限制拖拽范围。核心知识点包括:获取页面宽高、元素位置属性。代码中使用et.preventDefault()防止默认事件影响操作。该功能适用于提升用户体验。

vue项目中页面实现图标拖拽功能


最近在做项目需求时有个小功能:在页面的首页增加一个快速功能按钮,用来满足操作者快速实现某一目的渴望。为了体现代码搬运工的气质与水准,当时心想,这么简单的一个小东西必须给它整的明明白白。于是在页面的左上角完美的位置fixed了一个完美的图标,并配上骚气的颜色。就在一切功能都测试完毕,静待发版部署生产环境的时候,产品告诉我,这个按钮要在所有页面都有,而不单单只在首页!(所有页面就所有页面,只要把这个图标挪到组件的公共页里,不就可以简单的实现了嘛)于是一顿简单暴力的操作在我脑海里一一闪现。可是在图标全都放好才发现,每个页面的内容不同,样式也不一样,之前位置固定的图标就可能会覆盖在某些页面的按钮或图表上,这样即影响其他功能也不美观。于是图标支持拖拽迫在眉睫!(说了那么多废话,都是拖拽的炮灰 >_< ~)

实现思路:

  1. 按住鼠标左键进行拖动时获取鼠标对应位置的坐标;
  2. 通过鼠标坐标的变化,将坐标值换成图标距离窗口上(top)、左(left)的位置。

知识点:

  1. 获取最大拖拽宽高:
    window.innerHeight/innerWidth 页面的窗口的高/宽(包含工具条和滚动条);
    document.documentElement.clientHeight/clientWidth (html元素的高/宽);
    document.body.clientHeight/clientWidth (html中body的高/宽);
  2. 图标及鼠标位置:
    dom.offsetTop/offsetLeft (dom为获取的图标dom元素,offsetTop/offsetLeft为图标定位属性的top/left值----- 此值决定图标在页面上的实际位置);
    dom.offsetHeight/offsetWidth 可以理解为dom元素的实际高/宽;

代码实现:

  • 创建需要拖拽的元素并绑定鼠标事件
<template>
  <div>
    <span>{{msg}}</span>
    <div class="homeDiv" id="drag">
      <div class="iconClass" @dblclick="clickFunc" @mousedown="mousedown" @mousemove="mousemove" @mouseup="mouseup">
        <span class="spanClass">{{iconMsg}}</span>
      </div>
    </div>
  </div>
</template>
  • 拖拽时触发鼠标事件拿到并处理数据
export default{
    data(){
      return {
        msg:'图标按钮拖拽功能',
        iconMsg: '快来拖拽我~',

        dom: null,
        innerHeight: 0,
        innerWidth: 0,
        offsetHeight: 0,
        offsetWidth: 0,
        startX: 0,
        startY: 0,
        endX: 0,
        endY: 0,
        diffX: 0,
        diffY: 0,
        isDrag: false
      }
    },
    methods:{
      dragFunc(){
        this.dom = document.getElementById('drag');
        this.innerHeight= document.documentElement.clientHeight;
        this.innerWidth= document.documentElement.clientWidth;
        this.offsetHeight= this.dom.offsetHeight;
        this.offsetWidth=  this.dom.offsetWidth;
      },
      mousedown(e){
        this.isDrag= true;
        let et= e || window.event;
        this.startX= this.startY= et.clientX;
        this.endX= this.endY= et.clientY;
        this.diffY= et.clientY - this.dom.offsetTop;
        this.diffX= et.clientX - this.dom.offsetLeft;
        et.preventDefault();
      },
      mousemove(e){
        if(this.isDrag){
          let et= e || window.event;
          let currentX= et.clientX;
          let currentY= et.clientY;
          let my = currentY - this.diffY;
          let mx = currentX - this.diffX;
          let top,left;
          if(mx < 0){
            left= 0;
          }else if(mx > this.innerWidth - this.offsetWidth){
            left= this.innerWidth - this.offsetWidth;
          }else{
            left= mx;
          }
          if(my < 0){
            top= 0;
          }else if(my > this.innerHeight - this.offsetHeight){
            top= this.innerHeight - this.offsetHeight;
          }else{
            top= my;
          }
          this.dom.style.top= `${top}px`;
          this.dom.style.left= `${left}px`;
        }
      },
      mouseup(e){
        this.isDrag= false;
      },
      clickFunc(){
        console.log('快捷功能')
      }
    },
    mounted(){
      this.dragFunc();
    }
  }
  • 效果展示
    在这里插入图片描述
  • 代码中 et.preventDefault(); 方法作用是阻止默认事件的发生,若不阻止默认事件,由于图标中有文本内容,在我们拖动图标时就会出现如下情况,影响操作者的美好心情~
    在这里插入图片描述
  • 由于鄙人技术能力有限加之功能简单,看到这里所有的废话要告一段落了,希望这篇笔记对初次开发类似功能的小朋友们能有些许帮助,也欢迎各位大佬指点。江湖有缘定会再见,后会有期!~
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值