Vue实现dom元素拖拽并限制移动范围的操作代码

 更新时间:2023年12月04日 16:44:56   作者:Nicholson07  
这篇文章主要介绍了Vue实现dom元素拖拽并限制移动范围的操作代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

需求

       dom元素拖拽并限制在父组件范围内

拖拽功能封装

export const initVDrag = (vue) => {
	vue.directive('drag', (el) => {
		const oDiv = el // 当前元素
		oDiv.onmousedown = (e) => {
			let target = oDiv
			while (
				window.getComputedStyle(target).position !== 'absolute' &&
				target !== document.body
			) {
				target = target.parentElement
			}
			let parent = target.parentNode
			document.onselectstart = () => {
				return false
			}
			if (!target.getAttribute('init_x')) {
				target.setAttribute('init_x', target.offsetLeft)
				target.setAttribute('init_y', target.offsetTop)
			}
			// e.clientX, e.clientY是鼠标点击的位置
			// target.offsetLeft, target.offsetTop是当前元素左上角的位置
			// 计算鼠标按下的位置距离当前元素左上角的距离
			const disX = e.clientX - target.offsetLeft
			const disY = e.clientY - target.offsetTop
			// target.clientWidth, target.clientHeight是当前元素的尺寸
			// parent.clientWidth, parent.clientHeight是父元素的尺寸
			// parent.offsetLeft, parent.offsetTop是父元素左上角的位置
			// 可移动范围的位置
			const minX = parent.offsetLeft
			const maxX = parent.offsetLeft + parent.clientWidth - target.clientWidth
			const minY = parent.offsetTop
			const maxY = parent.offsetTop + parent.clientHeight - target.clientHeight
			document.onmousemove = (e) => {
				// 通过事件委托,计算移动的距离,e是最新的鼠标位置,disX、disY是鼠标刚点击时的位置
				let l = e.clientX - disX
				let t = e.clientY - disY
				// 约束移动范围在父元素区域内
				if (l < minX) {
					l = minX
				} else if (l > maxX) {
					l = maxX
				}
				if (t < minY) {
					t = minY
				} else if (t > maxY) {
					t = maxY
				}
				// 给当前元素样式中的left和top赋值
				target.style.left = l + 'px'
				target.style.top = t + 'px'
			}
			document.onmouseup = (e) => {
				document.onmousemove = null
				document.onmouseup = null
				document.onselectstart = null
			}
			// 不return false的话,可能导致鼠标黏连,鼠标粘在dom上拿不下来,相当于onmouseup失效
			return false
		}
	})
}

使用拖拽功能

        以vite为例:

vite-env.d.ts

...
declare module '@utils/directive/vDrag.js'
...

main.ts

...
import { createApp } from 'vue'
import { initVDrag } from '@/utils/directive/vDrag.js'
...
let instance: any = null
instance = createApp(App)
initVDrag(instance)
...

test.vue

<template>
    <div v-drag />
</template>

到此这篇关于Vue实现dom元素拖拽并限制移动范围的文章就介绍到这了,更多相关vue dom元素拖拽内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Vue-ECharts实现数据可视化图表功能

    使用Vue-ECharts实现数据可视化图表功能

    在前端开发中,经常会遇到需要展示数据可视化的需求,比如柱状图、折线图、饼图等,这类需求不仅要求我们准确地将数据呈现出来,还需要兼顾美观与交互体验,所以今天我们就来聊聊——Vue-ECharts,给大家介绍一下如何使用Vue-ECharts实现数据可视化图表功能
    2025-05-05
  • Vue项目中使用v-for指令进行列表渲染以及优化其性能

    Vue项目中使用v-for指令进行列表渲染以及优化其性能

    Vue中v-for用于列表渲染,需配合key属性提升性能,避免状态混乱,优化方法包括使用计算属性、虚拟滚动、减少内联事件等,确保key唯一且非索引
    2025-07-07
  • Vue3 keep-alive用法及说明

    Vue3 keep-alive用法及说明

    这篇文章主要介绍了Vue3 keep-alive用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2026-03-03
  • Vue实现购物车基本功能

    Vue实现购物车基本功能

    这篇文章主要为大家详细介绍了Vue实现购物车的基本功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • 在vue-cli创建的项目中使用sass操作

    在vue-cli创建的项目中使用sass操作

    这篇文章主要介绍了在vue-cli创建的项目中使用sass操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • VUE-cli3使用 svg-sprite-loader

    VUE-cli3使用 svg-sprite-loader

    svg-sprite-loader 的插件,用来根据导入的 svg 文件自动生成 symbol 标签并插入 html,这篇文章主要介绍了VUE-cli3使用 svg-sprite-loader,需要的朋友可以参考下
    2018-10-10
  • vue项目中公用footer组件底部位置的适配问题

    vue项目中公用footer组件底部位置的适配问题

    footer为公用组件,其他页面都需要引入。接下来通过本文给大家分享vue项目中公用footer组件底部位置的适配问题,需要的朋友可以参考下
    2018-05-05
  • VUE+elementui组件在table-cell单元格中绘制微型echarts图

    VUE+elementui组件在table-cell单元格中绘制微型echarts图

    这篇文章主要介绍了VUE+elementui组件在table-cell单元格中绘制微型echarts图,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • 针对Vue路由history模式下Nginx后台配置操作

    针对Vue路由history模式下Nginx后台配置操作

    这篇文章主要介绍了针对Vue路由history模式下Nginx后台配置操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Vue如何优雅地复制一行带附件的表格数据

    Vue如何优雅地复制一行带附件的表格数据

    在做 Vue 项目的时候,大家是不是经常遇到这样的需求,点一下复制按钮,把这行表格数据复制一份放在下方,除了附件字段之外其他都保留,所以本文我们就来看看如何优雅地复制一行带附件的数据,不破坏原始数据结构吧
    2025-09-09

最新评论