鼠标拖拽问题,不选中文本不触发单击事件

文章目录

  • 1. 为什么鼠标单击的时候触发了`mousemove`事件?明明鼠标没有移动
  • 2. 鼠标拖拽元素怎么能不触发单击事件?怎么处理鼠标在元素内的相对定位,而不是每次定位到左上角?
    • 方式一:拖拽的元素没有注册click监听就不会触发单击事件绑定的函数
    • 方式二:通过鼠标是否发生移动判断当前元素是需要移动还是需要单击
    • 方式三:考虑鼠标在元素内相对定位问题,鼠标点击位置就是拖拽位置
  • 3. 鼠标拖拽元素怎么能不触发选中文本?
    • 方式一:鼠标按下时,阻止默认事件`e.preventDefault()`,不触发选中文本
    • 方式二:鼠标按下时,修改当前元素style样式,鼠标抬起再取消
  • 参考链接

        鼠标拖拽需要注意什么问题?
        鼠标拖拽会依次触发mousedown mousemove mouseup click事件。很多时候在一个元素既需要拖拽又需要单击的时候,应该怎么避免在拖拽时不触发单击事件?不触发文本选中问题?

1. 为什么鼠标单击的时候触发了mousemove事件?明明鼠标没有移动

2. 鼠标拖拽元素怎么能不触发单击事件?怎么处理鼠标在元素内的相对定位,而不是每次定位到左上角?

方式一:拖拽的元素没有注册click监听就不会触发单击事件绑定的函数

  1. 示例代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>测试拖拽</title><style>body{background-color: #f5f5f5;}#triggerDiv {position: fixed;left: 0px;top: 0px;width: 100px;height: 100px;background-color: red;position: absolute;text-align: center;line-height: 100px;vertical-align: middle;cursor: pointer;border-radius: 50%;}</style>
</head>
<body><div id="triggerDiv">拖拽</div>
</body><script>let triggerELe = document.getElementById('triggerDiv')let isMouseDown = false// 鼠标按下triggerELe.addEventListener('mousedown', function(e) {isMouseDown = trueconsole.log('mousedown:', isMouseDown)})// 鼠标移动triggerELe.addEventListener('mousemove', function(e) {console.log('mousemove:', isMouseDown)if (isMouseDown) {triggerELe.style.left = e.clientX + 'px'triggerELe.style.top = e.clientY + 'px'}})// 鼠标抬起triggerELe.addEventListener('mouseup', function(e) {isMouseDown = falseconsole.log('mouseup:', isMouseDown)})// 鼠标离开:事件顺序 mouseout > mouseleave// triggerELe.addEventListener('mouseout', function(e) {//     isMouseDown = false//     console.log('mouseout:', isMouseDown)// })// triggerELe.addEventListener('mouseleave', function(e) {//     isMouseDown = false//     console.log('mouseleave:', isMouseDown)// })// 给元素绑定了单击事件// triggerELe.addEventListener('click', function(e) {//     console.log('click')// })
</script>
</html>
  1. 通过对比是否绑定单击事件,判断单击是否被触发

image.pngimage.png

方式二:通过鼠标是否发生移动判断当前元素是需要移动还是需要单击

  1. 如果mousemove事件没有被触发,那mouseup发生时当前元素应该执行单击事件
    1. 示例代码
<script>let triggerELe = document.getElementById('triggerDiv')let isMouseDown = false // 鼠标是否按下let isMouseMove = false // 鼠标是否发生移动// 鼠标按下triggerELe.addEventListener('mousedown', function(e) {console.log('mousedown')isMouseDown = trueisMouseMove = false})// 鼠标移动triggerELe.addEventListener('mousemove', function(e) {console.log('mousemove')isMouseMove = trueif (isMouseDown) {triggerELe.style.left = e.clientX + 'px'triggerELe.style.top = e.clientY + 'px'}})// 鼠标抬起triggerELe.addEventListener('mouseup', function(e) {console.log('mouseup')isMouseDown = falseif (isMouseMove) {console.log('鼠标移动了')} else {console.log('鼠标没有移动,执行单击事件')}})
</script>
  1. 通过判断是否触发mousemove事件,决定是否执行单击事件

image.png

  1. 如果mousedownmouseup事件发生后,鼠标位置没有改变应该执行单击事件
    1. 示例代码
<script>let triggerELe = document.getElementById('triggerDiv')let isMouseDown = false // 鼠标是否按下// ========= 鼠标移动相关变量 ===========let beforeX = 0 // 鼠标按下时的x坐标let beforeY = 0 // 鼠标按下时的y坐标let afterX = 0 // 鼠标抬起时的x坐标let afterY = 0 // 鼠标抬起时的y坐标// 鼠标按下triggerELe.addEventListener('mousedown', function(e) {console.log('mousedown')isMouseDown = truebeforeX = e.offsetXbeforeY = e.offsetY})// 鼠标移动triggerELe.addEventListener('mousemove', function(e) {console.log('mousemove')if (isMouseDown) {triggerELe.style.left = e.clientX + 'px'triggerELe.style.top = e.clientY + 'px'}})// 鼠标抬起triggerELe.addEventListener('mouseup', function(e) {console.log('mouseup')isMouseDown = falseafterX = e.offsetXafterY = e.offsetYconsole.log('beforeX:', beforeX, 'beforeY:', beforeY, 'afterX:', afterX, 'afterY:', afterY)// 前后坐标相等,说明没有移动,执行单击事件if (beforeX !== afterX || beforeY !== afterY) {console.log('鼠标移动了')} else {console.log('鼠标没有移动,执行单击事件')}})// // 给元素绑定了单击事件// triggerELe.addEventListener('click', function(e) {//     console.log('click')// })
</script>
  1. 思路:如果鼠标前后坐标没有发生变化执行单击事件

image.png
注!由于页面缩放问题,可能会出现鼠标没有移动但是前后坐标不一致的问题。

方式三:考虑鼠标在元素内相对定位问题,鼠标点击位置就是拖拽位置

<script>let triggerELe = document.getElementById('triggerDiv')let isMouseDown = false // 鼠标是否按下// ========= 鼠标移动相关变量 ===========let beforeX = 0 // 鼠标按下时的x坐标let beforeY = 0 // 鼠标按下时的y坐标let afterX = 0 // 鼠标抬起时的x坐标let afterY = 0 // 鼠标抬起时的y坐标let initX = 0 // 鼠标按下时的x坐标let initY = 0 // 鼠标按下时的y坐标// 鼠标按下triggerELe.addEventListener('mousedown', function(e) {console.log('mousedown')isMouseDown = truebeforeX = e.offsetXbeforeY = e.offsetY// 鼠标按下时的坐标initX = e.offsetXinitY = e.offsetY})// 鼠标移动triggerELe.addEventListener('mousemove', function(e) {console.log('mousemove')if (isMouseDown) {triggerELe.style.left = (e.clientX - initX) + 'px'triggerELe.style.top = (e.clientY - initY) + 'px'// 鼠标移动时的坐标afterX = e.offsetX + 'px'afterY = e.clientY + 'px'}})// 鼠标抬起triggerELe.addEventListener('mouseup', function(e) {console.log('mouseup')isMouseDown = falseafterX = e.offsetXafterY = e.offsetYconsole.log('beforeX:', beforeX, 'beforeY:', beforeY, 'afterX:', afterX, 'afterY:', afterY)// 前后坐标相等,说明没有移动,执行单击事件if (beforeX !== afterX || beforeY !== afterY) {console.log('鼠标移动了')} else {console.log('鼠标没有移动,执行单击事件')}})// // 给元素绑定了单击事件// triggerELe.addEventListener('click', function(e) {//     console.log('click')// })
</script>

3. 鼠标拖拽元素怎么能不触发选中文本?

方式一:鼠标按下时,阻止默认事件e.preventDefault(),不触发选中文本

<script>let triggerELe = document.getElementById('triggerDiv')let isMouseDown = false // 鼠标是否按下// ========= 鼠标移动相关变量 ===========let beforeX = 0 // 鼠标按下时的x坐标let beforeY = 0 // 鼠标按下时的y坐标let afterX = 0 // 鼠标抬起时的x坐标let afterY = 0 // 鼠标抬起时的y坐标let initX = 0 // 鼠标按下时的x坐标let initY = 0 // 鼠标按下时的y坐标// 鼠标按下triggerELe.addEventListener('mousedown', function(e) {console.log('mousedown')isMouseDown = truebeforeX = e.offsetXbeforeY = e.offsetY// 鼠标按下时的坐标initX = e.offsetXinitY = e.offsetY// 阻止默认事件e.preventDefault()})// 鼠标移动triggerELe.addEventListener('mousemove', function(e) {console.log('mousemove')if (isMouseDown) {triggerELe.style.left = (e.clientX - initX) + 'px'triggerELe.style.top = (e.clientY - initY) + 'px'// 鼠标移动时的坐标afterX = e.offsetX + 'px'afterY = e.clientY + 'px'}})// 鼠标抬起triggerELe.addEventListener('mouseup', function(e) {console.log('mouseup')isMouseDown = falseafterX = e.offsetXafterY = e.offsetYconsole.log('beforeX:', beforeX, 'beforeY:', beforeY, 'afterX:', afterX, 'afterY:', afterY)// 前后坐标相等,说明没有移动,执行单击事件if (beforeX !== afterX || beforeY !== afterY) {console.log('鼠标移动了')} else {console.log('鼠标没有移动,执行单击事件')}})// // 给元素绑定了单击事件// triggerELe.addEventListener('click', function(e) {//     console.log('click')// })
</script>

方式二:鼠标按下时,修改当前元素style样式,鼠标抬起再取消

<script>let triggerELe = document.getElementById('triggerDiv')let isMouseDown = false // 鼠标是否按下// ========= 鼠标移动相关变量 ===========let beforeX = 0 // 鼠标按下时的x坐标let beforeY = 0 // 鼠标按下时的y坐标let afterX = 0 // 鼠标抬起时的x坐标let afterY = 0 // 鼠标抬起时的y坐标let initX = 0 // 鼠标按下时的x坐标let initY = 0 // 鼠标按下时的y坐标// 鼠标按下triggerELe.addEventListener('mousedown', function(e) {console.log('mousedown')isMouseDown = truebeforeX = e.offsetXbeforeY = e.offsetY// 鼠标按下时的坐标initX = e.offsetXinitY = e.offsetY// 不选中文字triggerELe.style.userSelect = 'none'// 添加css// css// .no-select {//  user-select: none// }})// 鼠标移动triggerELe.addEventListener('mousemove', function(e) {console.log('mousemove')if (isMouseDown) {triggerELe.style.left = (e.clientX - initX) + 'px'triggerELe.style.top = (e.clientY - initY) + 'px'// 鼠标移动时的坐标afterX = e.offsetX + 'px'afterY = e.clientY + 'px'}})// 鼠标抬起triggerELe.addEventListener('mouseup', function(e) {console.log('mouseup')isMouseDown = falseafterX = e.offsetXafterY = e.offsetYconsole.log('beforeX:', beforeX, 'beforeY:', beforeY, 'afterX:', afterX, 'afterY:', afterY)// 前后坐标相等,说明没有移动,执行单击事件if (beforeX !== afterX || beforeY !== afterY) {console.log('鼠标移动了')// 移除css// .no-select {//  user-select: text// }triggerELe.style.userSelect = 'text'} else {console.log('鼠标没有移动,执行单击事件')}})// // 给元素绑定了单击事件// triggerELe.addEventListener('click', function(e) {//     console.log('click')// })
</script>

参考链接

可拖动DIV层的实现方法_可拖动的div-CSDN博客
Javascript设置拖拽时不触发点击事件_鼠标拖动列表,会触发列表项的点击事件,如何阻止-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/167024.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10年测试老鸟,自动化测试经验10条建议,一路狂飙...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、哪一刻&#x…

Postman如何使用(二):Postman Collection的创建/使用/导出分享等

一、什么是Postman Collection&#xff1f; Postman Collection是可让您将各个请求分组在一起。 您可以将这些请求组织到文件夹中。中文经常将collection翻译成收藏夹。如果再下文中看到这样的翻译不要觉得意外。Postman Collection会使你的工作效率更上一层楼。Postman Colle…

教师工作就业前景

在这个知识爆炸的时代&#xff0c;当老师无疑是社会发展的重要基石。随着科技的进步和社会的发展&#xff0c;教育行业的需求也在不断增长。那么&#xff0c;教师工作的就业前景如何呢&#xff1f; 我们来看看教师工作的市场需求。随着国家对教育的重视和投入的增加&#xff0c…

C/C++ 实现Socket交互式服务端

在 Windows 操作系统中&#xff0c;原生提供了强大的网络编程支持&#xff0c;允许开发者使用 Socket API 进行网络通信&#xff0c;通过 Socket API&#xff0c;开发者可以创建、连接、发送和接收数据&#xff0c;实现网络通信。本文将深入探讨如何通过调用原生网络 API 实现同…

「Java开发中文指南」IntelliJ IDEA插件安装(一)

IntelliJ IDEA是java编程语言开发的集成环境。IntelliJ在业界被公认为最好的Java开发工具&#xff0c;尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能是非常强大的。 插件扩展了Intel…

【分布式】分布式中的时钟

一、物理时钟 vs 逻辑时钟 时钟的存在主要是为了标识事件的发生顺序。 分布式系统不使用物理时钟记录事件&#xff0c;分布式系统中每个节点记录的时间并不一样&#xff0c;即使设置了 NTP 时间同步节点间也存在毫秒级别的偏差 所以需要有另外的方法记录事件顺序关系&#x…

vue2中使用echarts

1,安装echarts npm install --save echarts 2&#xff0c;具体页面 <template><div class"app-container"><div class"aa" id"main" style"width: 500px; height: 400px;"></div></div> </te…

PDF 批量处理软件BatchOutput PDF mac中文版介绍

BatchOutput PDF mac是一款适用于 Mac 的 PDF 批量处理软件。它可以帮助用户将多个 PDF 文件进行异步处理&#xff0c;提高工作效率。 BatchOutput PDF 可以自动化执行许多任务&#xff0c;包括 PDF 文件的打印、转换、分割、压缩、加密、重命名等&#xff0c;而且它还可以将自…

Elasticsearch知识

目录 Elasticsearch逻辑设计和物理设计 逻辑设计物理设计Elasticsearch原理 倒排索引文档的分析过程保存文档搜索文档写数据的底层原理 数据刷新&#xff08;fresh&#xff09;事务日志的写入ES在大数据量下的性能优化 文件系统缓存优化数据预热文档&#xff08;Document&…

【数据分享】2023年我国省市县三级的瞪羚企业数量(免费获取/Excel/Shp格式)

企业是经济活动的参与主体。一个城市的企业数量决定了这个城市的经济发展水平&#xff01;比如一个城市的金融企业较多&#xff0c;那这个城市的金融产业肯定比较发达&#xff1b;一个城市的制造业企业较多&#xff0c;那这个城市的制造业肯定比较发达。 之前我们给大家分享了…

《opencv实用探索·二》根据RGB的像素排列来理解图像深度、像素深度和位深度

通常对于RGB图像主要分为RGB16&#xff0c;RGB24和RGB32。RGB16从高位到低位的排列为R->G->B&#xff0c;RGB24和RGB32从高位到低位的排列为B->G->R。 RGB16: 16 位为一个存储单元&#xff08;一个像素&#xff09;&#xff0c;来存储一个RGB像素;因为人眼对绿色比…

社区物联网云服务架构设计

文章目录 1 摘要2 架构图2.1 社区物联网云服务网络拓扑图2.2 社区物联网云服务通讯流程图2.3 社区远程开锁功能流程图 3 应用场景 1 摘要 随着社区管理越来越智能化&#xff0c;社区物联网升级与改造的市场空间也越来越大。社区物联网包含楼宇对讲、门禁门锁、通道闸等等设备系…

Netty 模型理解

参考文章 1 参考文章 2 官网API文档 Reactor模型 Netty模型 Netty主要基于主从Reactor多线程模型进行了一定的修改&#xff0c;该模型包括以下几个组件&#xff1a; MainReactor&#xff08;主Reactor&#xff09;&#xff1a;负责处理客户端的连接请求。它监听服务器上的端口…

中电金信:守【政】创新,探路保险数字化转型“新范式”

11月23日&#xff0c;CIIP2023中国保险科技创新合作大会在京举办。大会汇集保险科技领域行业专家、学者、国内外头部险企及保险科技公司负责人等各界人士&#xff0c;立足保险行业高质量发展和创新驱动理念&#xff0c;寻找行业数字化转型新动能、新视角&#xff0c;为保险科技…

python中range函数的用法

range() 是Python的一个内置函数。语法格式为&#xff1a;range(start, stop, step) start是初始值&#xff0c;stop是最终值&#xff0c;step是步长。range()函数仅适用于整数&#xff0c;所有参数都必须是整数。步长值可以为正数或负数&#xff0c;不得为零。使用range函数时…

如何去掉图片水印不伤原图?无痕去水印教程分享!

如何去掉图片水印不伤原图&#xff1f;在电商广告设计和营销领域&#xff0c;水印已经成为一种常见的版权保护手段。不过&#xff0c;水印也给淘宝商家带来了一些困扰。那么如何去掉图片水印还能不伤原图呢&#xff0c;接下来&#xff0c;将分享简单好用的无痕去水印教程&#…

Rust UI开发(二):iced中如何为窗口添加icon图标

注&#xff1a;此文适合于对rust有一些了解的朋友 iced是一个跨平台的GUI库&#xff0c;用于为rust语言程序构建UI界面。 想要了解如何构建简单窗口的可以看本系列的第一篇&#xff1a; Rust UI开发&#xff1a;使用iced构建UI时&#xff0c;如何在界面显示中文字符 本篇是系…

VMware 虚拟机设置静态IP

1.桥接模式&#xff1a;无线网卡虚拟机可以桥接的&#xff0c;Vmware0是虚拟机默认进入的虚拟网络&#xff0c;打开虚拟网络编辑器把Vmware0桥接到具体的无线网卡上&#xff0c;再打开网卡设置选择桥接模式即可。 2、.NAT模式下 &#xff1a;window下VMnet8: IPv4 地址 . . . …

高级IO—select

高级IO—select 文章目录 高级IO—selectIO的概念 五种IO模型阻塞IO非阻塞IO信号驱动IOIO多路转接异步IO I/O多路转接之select IO的概念 通常指数据在内部存储器和外部存储器或其他周边设备之间的输入和输出。输入是系统接收的信号或数据&#xff0c;输出则是从其发送的信号或…

Jmeter接口测试——使用教程(下)

前言 上一篇我给大家讲了jmeter的基本介绍跟参数化和jmeter脚本及jmeter断言&#xff0c;今天让我们继续往下看&#xff0c;学习一下jmeter新的知识点。 一、Jmeter关联 我们知道断言是从返回结果中检查有没有预期的值&#xff0c;现在有一个问题&#xff0c;有一个购买商品…