前端实现界面元素拖拽功能的3种方式总结(亲测有效)

 更新时间:2025年02月08日 10:04:04   作者:前端白袍  
这篇文章主要介绍了前端实现界面元素拖拽功能的3种方式,三种方法分别是纯HTML+CSS+JS、Vue模板和Vue全局指令,每种方法都通过监听鼠标事件来实现元素的拖动功能,并通过控制阀来确保只有在指定区域按下鼠标时才开始拖动,需要的朋友可以参考下

一、纯HTML+CSS+JS实现;

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="draggableDialog">
    <div class="dialog-header">弹框标题</div>
    <div class="dialog-content">弹框内容</div>
</div>
</body>
<style>
  #draggableDialog {
    position: absolute;
    width: 300px;
    height: 200px;
    background-color: #fff;
    border: 1px solid #ccc;
    padding: 10px;
}
.dialog-header {
    cursor: move;
    background-color: #f0f0f0;
    padding: 5px;
}
</style>
<script>
const dialog = document.getElementById('draggableDialog');
const dialogHeader = dialog.querySelector('.dialog-header');
let isDragging = false;
let offsetX, offsetY;
dialogHeader.addEventListener('mousedown', (e) => {
    isDragging = true;
    offsetX = e.clientX - dialog.offsetLeft;
    offsetY = e.clientY - dialog.offsetTop;
});
document.addEventListener('mousemove', (e) => {
    if (isDragging) {
        dialog.style.left = e.clientX - offsetX + 'px';
        dialog.style.top = e.clientY - offsetY + 'px';
    }
});
document.addEventListener('mouseup', () => {
    isDragging = false;
});
</script>
</html>

实现原理:使用js事件监听,监听document全局DOM的鼠标移动事件,当触发事件后,目标元素将会随鼠标一起偏移(移动)相对应的距离;因目标元素并非一直需要跟随鼠标移动,于是通过给目标元素指定区域dialogHeader 添加鼠标按下事件配合isDragging控制阀,实现只有当鼠标在指定区域按下才能实现拖动目标元素的效果。

二、VUE模板实现;

<template>
  <div id="draggableDialog" ref="dialog">
    <div class="dialog-header" @mousedown="startDrag($event)">弹框标题</div>
    <div class="dialog-content">弹框内容</div>
  </div>
</template>
 
<script>
export default {
  data() {
    return {
      isDragging: false,
      offsetX: 0,
      offsetY: 0
    };
  },
  methods: {
    startDrag(event) {
      this.isDragging = true;
      this.offsetX = event.clientX - this.$refs.dialog.offsetLeft;
      this.offsetY = event.clientY - this.$refs.dialog.offsetTop;
      document.addEventListener('mousemove', this.drag);
      document.addEventListener('mouseup', this.stopDrag);
    },
    drag(event) {
      if (this.isDragging) {
        this.$refs.dialog.style.left = event.clientX - this.offsetX + 'px';
        this.$refs.dialog.style.top = event.clientY - this.offsetY + 'px';
      }
    },
    stopDrag() {
      this.isDragging = false;
      document.removeEventListener('mousemove', this.drag);
      document.removeEventListener('mouseup', this.stopDrag);
    }
  }
};
</script>
 
<style>
#draggableDialog {
  position: absolute;
  width: 300px;
  height: 200px;
  background-color: #fff;
  border: 1px solid #ccc;
  padding: 10px;
}
 
.dialog-header {
  cursor: move;
  background-color: #f0f0f0;
  padding: 5px;
}
</style>

原理同上;

三、VUE全局指令实现;

Vue.directive('drag', {
    bind(el) {
        el.onmousedown = function(e) {
            let disX = e.clientX - el.offsetLeft;
            let disY = e.clientY - el.offsetTop;
            document.onmousemove = function(e) {
                let left = e.clientX - disX;
                let top = e.clientY - disY;
                if (left < 0) left = 0;
                if (top < 0) top = 0;
                if (left > document.documentElement.clientWidth - el.offsetWidth) left = document.documentElement.clientWidth - el.offsetWidth;
                if (top > document.documentElement.clientHeight - el.offsetHeight) top = document.documentElement.clientHeight - el.offsetHeight;
                el.style.left = left + 'px';
                el.style.top = top + 'px';
            };
            document.onmouseup = function() {
                document.onmousemove = null;
                document.onmouseup = null;
            };
        };
    }
});

总结 

到此这篇关于前端实现界面元素拖拽功能的3种方式的文章就介绍到这了,更多相关前端实现界面元素拖拽内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • bootstrap 日期控件 datepicker被弹出框dialog覆盖的解决办法

    bootstrap 日期控件 datepicker被弹出框dialog覆盖的解决办法

    这篇文章主要介绍了bootstrap 日期控件 datepicker被弹出框dialog覆盖的解决办法 ,本文给大家分享几种解决方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • 原生JS与jQuery编写简单选项卡

    原生JS与jQuery编写简单选项卡

    这篇文章主要为大家详细介绍了原生JS与jQuery编写简单选项卡,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • js 用CreateElement动态创建标签示例

    js 用CreateElement动态创建标签示例

    用CreateElement动态创建标签,主要是html中常用的一些标签,在本文有详细的示例,喜欢的朋友可以参考下
    2013-11-11
  • 前端地图(openlayers)基础使用示例代码

    前端地图(openlayers)基础使用示例代码

    这篇文章主要介绍了前端地图(openlayers)基础使用的相关资料,OpenLayers是开源地图框架,支持加载国内外地图服务(如天地图),提供瓦片、矢量、影像图层,需要的朋友可以参考下
    2025-07-07
  • 微信公众号服务器验证Token步骤图解

    微信公众号服务器验证Token步骤图解

    这篇文章主要介绍了微信公众号服务器验证Token步骤图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 浅析JavaScript中如何正确判断null和undefined

    浅析JavaScript中如何正确判断null和undefined

    这篇文章主要为大家详细介绍了JavaScript中如何正确判断null和undefined,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以了解下
    2026-01-01
  • Javascript 强制类型转换函数

    Javascript 强制类型转换函数

    javascript是弱类型的语言,所以强制类型转换还是比较重要的,下面看一下它的几个强制转换的函数
    2009-05-05
  • 详细聊聊JS中不一样的深拷贝

    详细聊聊JS中不一样的深拷贝

    对于js中的对象的深拷贝在项目的开发中比较常用到,这篇文章主要给大家介绍了关于JS中不一样的深拷贝的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • Javascript 浮点运算的问题分析与解决方法

    Javascript 浮点运算的问题分析与解决方法

    JavaScript 只有一种数字类型 Number ,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的。 浮点数的精度问题不是JavaScript特有的,因为有些小数以二进制表示位数是无穷的
    2013-08-08
  • JS特权方法定义作用以及与公有方法的区别

    JS特权方法定义作用以及与公有方法的区别

    在构造函数内部通过this关键字定义的的方法为特权方法它的作用为在构造函数外面公开访问(仅限于实例化的对象),而且还能够访问私有成员和方法,感兴趣的你可以参考下哈
    2013-03-03

最新评论