vue如何解决鼠标进行拖拽时禁止选中其他元素

Vue如何解决鼠标进行拖拽时禁止选中其他元素

实现这个方法很简单,我们只需在你想要禁用指定元素的拖动选项即可

加入以下代码

unselectable="on"
onselectstart="return false"
style="-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;"

加入以上代码来适配不同的浏览器

好啦,这样问题就解决啦!

### 鼠标左键框选功能与整体拖拽实现原理 在 Vue3 中实现鼠标左键框选功能以及支持选中元素的整体拖拽,需要结合事件监听、DOM 操作和状态管理来完成。以下是实现的核心原理和技术: 1. **框选区域的创建**:通过监听鼠标的按下 (`mousedown`) 和移动 (`mousemove`) 事件,在画布上动态生成一个透明的 `div` 元素作为框选区域。 2. **元素检测**:在鼠标释放 (`mouseup`) ,检查框选区域内有哪些目标元素,并将这些元素标记为选中状态[^1]。 3. **整体拖拽**:为选中元素绑定拖拽逻辑,当用户按下鼠标并移动,更新所有选中元素的位置[^2]。 以下是完整的实现代码示例: ```vue <template> <div class="container" @mousedown="handleMouseDown" @mousemove="handleMouseMove" @mouseup="handleMouseUp"> <div v-for="(item, idx) in list" :key="idx" class="item" :style="{ left: item.x + &#39;px&#39;, top: item.y + &#39;px&#39; }" :class="{ selected: item.selected }" @mousedown.stop="handleItemMouseDown(item)" > {{ item.name }} </div> <div v-if="isSelecting" class="selection-box" :style="{ left: selectionStartX + &#39;px&#39;, top: selectionStartY + &#39;px&#39;, width: selectionWidth + &#39;px&#39;, height: selectionHeight + &#39;px&#39; }"></div> </div> </template> <script> import { ref, reactive } from "vue"; export default { setup() { const list = reactive([ { name: "Item 1", x: 50, y: 50, selected: false }, { name: "Item 2", x: 150, y: 50, selected: false }, { name: "Item 3", x: 50, y: 150, selected: false }, { name: "Item 4", x: 150, y: 150, selected: false }, ]); const isSelecting = ref(false); const selectionStartX = ref(0); const selectionStartY = ref(0); const selectionEndX = ref(0); const selectionEndY = ref(0); const handleMouseDown = (e) => { if (e.button !== 0) return; // 只处理左键 isSelecting.value = true; selectionStartX.value = e.clientX; selectionStartY.value = e.clientY; selectionEndX.value = e.clientX; selectionEndY.value = e.clientY; }; const handleMouseMove = (e) => { if (!isSelecting.value) return; selectionEndX.value = e.clientX; selectionEndY.value = e.clientY; }; const handleMouseUp = () => { if (!isSelecting.value) return; isSelecting.value = false; const rect = { left: Math.min(selectionStartX.value, selectionEndX.value), right: Math.max(selectionStartX.value, selectionEndX.value), top: Math.min(selectionStartY.value, selectionEndY.value), bottom: Math.max(selectionStartY.value, selectionEndY.value), }; list.forEach((item) => { const itemRect = { left: item.x, right: item.x + 50, // 假设每个元素宽高为50 top: item.y, bottom: item.y + 50, }; item.selected = !(rect.right < itemRect.left || rect.left > itemRect.right || rect.bottom < itemRect.top || rect.top > itemRect.bottom); }); }; const handleItemMouseDown = (item) => { if (!item.selected) return; const startX = item.x; const startY = item.y; const onMouseMove = (e) => { item.x = startX + e.movementX; item.y = startY + e.movementY; }; const onMouseUp = () => { document.removeEventListener("mousemove", onMouseMove); document.removeEventListener("mouseup", onMouseUp); }; document.addEventListener("mousemove", onMouseMove); document.addEventListener("mouseup", onMouseUp); }; return { list, isSelecting, selectionStartX, selectionStartY, selectionWidth: computed(() => Math.abs(selectionEndX.value - selectionStartX.value)), selectionHeight: computed(() => Math.abs(selectionEndY.value - selectionStartY.value)), handleMouseDown, handleMouseMove, handleMouseUp, handleItemMouseDown, }; }, }; </script> <style> .container { position: relative; width: 400px; height: 400px; border: 1px solid #ccc; overflow: hidden; } .item { position: absolute; width: 50px; height: 50px; background-color: lightblue; cursor: move; } .item.selected { background-color: lightgreen; } .selection-box { position: absolute; border: 1px dashed red; pointer-events: none; } </style> ``` ### 实现细节说明 - **框选区域动态生成**:通过 `mousedown` 和 `mousemove` 事件计算框选区域的起和终,动态调整其大小和位置。 - **元素检测**:在 `mouseup` 事件中,根据框选区域的坐标范围,判断哪些元素被包含在内,并将其标记为选中状态。 - **整体拖拽**:为选中元素绑定拖拽事件,当用户移动鼠标,更新所有选中元素的位置[^2]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值