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

文章目录

  • 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 = true
        console.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 = false
        console.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 = true
        isMouseMove = false
    })

    // 鼠标移动
    triggerELe.addEventListener('mousemove', function(e) {
        console.log('mousemove')
        isMouseMove = true
        if (isMouseDown) {
            triggerELe.style.left = e.clientX + 'px'
            triggerELe.style.top = e.clientY + 'px'
        }
    })

    // 鼠标抬起
    triggerELe.addEventListener('mouseup', function(e) {
        console.log('mouseup')
        isMouseDown = false

        if (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 = true

        beforeX = e.offsetX
        beforeY = 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 = false

        afterX = e.offsetX
        afterY = e.offsetY

        console.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 = true

        beforeX = e.offsetX
        beforeY = e.offsetY

        // 鼠标按下时的坐标
        initX = e.offsetX
        initY = 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 = false

        afterX = e.offsetX
        afterY = e.offsetY

        console.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 = true

        beforeX = e.offsetX
        beforeY = e.offsetY

        // 鼠标按下时的坐标
        initX = e.offsetX
        initY = 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 = false

        afterX = e.offsetX
        afterY = e.offsetY

        console.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 = true

        beforeX = e.offsetX
        beforeY = e.offsetY

        // 鼠标按下时的坐标
        initX = e.offsetX
        initY = 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 = false

        afterX = e.offsetX
        afterY = e.offsetY

        console.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博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python报错:AttributeError(类属性、实例属性)

Python报错&#xff1a;AttributeError&#xff08;类属性、实例属性&#xff09; Python报错&#xff1a;AttributeError 这个错误就是说python找不到对应的对象的属性&#xff0c;百度后才发现竟然是初始化类的时候函数名写错了 __init__应该有2条下划线&#xff0c;如果只有…

北邮22级信通院数电:Verilog-FPGA(11)第十一周实验(2)设计一个24秒倒计时器

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.代码部分 1.1 counter_24.v 1.2 divid…

【深度学习】CNN中pooling层的作用

1、pooling是在卷积网络&#xff08;CNN&#xff09;中一般在卷积层&#xff08;conv&#xff09;之后使用的特征提取层&#xff0c;使用pooling技术将卷积层后得到的小邻域内的特征点整合得到新的特征。一方面防止无用参数增加时间复杂度&#xff0c;一方面增加了特征的整合度…

2、用命令行编译Qt程序生成可执行文件exe

一、创建源文件 1、新建一个文件夹&#xff0c;并创建一个txt文件 2、重命名为main.cpp 3、在main.cpp中添加如下代码 #include <QApplication> #include <QDialog> #include <QLabel> int main(int argc, char *argv[]) { QApplication a(argc, argv); QDi…

在Spring Boot中实现单文件,多文件上传

这篇文章算是一篇水文&#xff0c;因为也没啥好讲的&#xff0c;在Spring Boot中&#xff0c;上传文件是我们常常做的&#xff0c;包括我们在实际开发过程中&#xff0c;我们也经常碰到与文件上传有关的功能&#xff0c;这也算是我们常用的一个功能了&#xff0c;毕竟作为开发者…

分布式数据恢复-hbase+hive分布式存储误删除如何恢复数据?

hbasehive分布式存储数据恢复环境&#xff1a; 16台某品牌R730XD服务器节点&#xff0c;每台物理服务器节点上有数台虚拟机&#xff0c;虚拟机上配置的分布式&#xff0c;上层部署hbase数据库hive数据仓库。 hbasehive分布式存储故障&初检&#xff1a; 数据库文件被误删除…

HarmonyOS应用开发实战—登录页面【ArkTS】

文章目录 本页面实战效果预览图一.HarmonyOS应用开发1.1HarmonyOS 详解1.2 ArkTS详解二.HarmonyOS应用开发实战—登录页面【ArkTS】2.1 ArkTS页面源码2.2 代码解析2.3 心得本页面实战效果预览图 一.HarmonyOS应用开发 1.1HarmonyOS 详解 HarmonyOS(鸿蒙操作系统)是华为公司…

【unity实战】基于权重的随机事件(附项目源码)

文章目录 前言开始一、简单的使用二、完善各种事件1. 完善生成金币事件2. 完善生成敌人事件敌人3. 完善生成药水事件 最终效果参考源码完结 前言 随机功能和UnityEvent前面其实我们都已经做过了&#xff0c;但是随机UnityEvent事件要怎么使用呢&#xff1f;这里就来举一个例子…

Vue3+element-plus,打包报错:Cannot read properties of null (reading ‘insertBefore‘)

一、现象&#xff1a;vue3 element-plus项目&#xff0c;本地启动时&#xff0c;页面所有操作都正常&#xff1b;部署到生产环境后&#xff0c;el-dialog、el-drawer弹框报错。 这个弹框报错问题&#xff0c;困扰好几天&#xff0c;查阅资料&#xff0c;可能是如下几个问题。 …

白嫖CTG4.0

大家好&#xff0c;到点了我来给各位大佬献策CTG&#xff0c;不是花钱买不起&#xff0c;而是免费更有性价比&#xff0c;哈哈哈不调侃了我们自此开始正文&#xff0c;咱们主打的就是一个分享是一种态度 当然我更希望大家支持国产对国产有自己的信心&#xff08;文心一言&…

鸿蒙4.0开发笔记之DevEco Studio如何使用低代码开发模板进行开发的详细流程(六)

鸿蒙低代码开发 一、什么是低代码二、如何进行鸿蒙低代码开发1、 创建低代码开发工程&#xff08;方式壹&#xff09;2、已有工程则创建Visual文件&#xff08;方拾贰&#xff09; 三、低代码开发界面介绍四、低代码实现页面跳转五、低代码开发建议 一、什么是低代码 所谓低代码…

数据结构——单链表(Singly Linked List)

1.链表介绍 链表是一种物理储存上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点&#xff08;链表中每一个元素称为结点&#xff09;组成&#xff0c;结点可以在运行时动态生成。 对于上图&#xff0c;每一个结点都是一个结…

C语言—指针和数组

写在前 一个指针变量指向某个普通变量&#xff0c;则指针变量就等于普通变量。 指针变量存放的是地址&#xff0c;普通变量存放的是数据。 int * p; int i5,j; p &i;此程序&#xff0c;*pi5&#xff0c;在所有出现 *p 或 i 的位置&#xff0c;两者都可以互相替换。 通过…

2023年亚太杯数学建模A题水果采摘机器人的图像识别功能(基于yolov5的苹果分割)

注&#xff1a;.题中附录并没有给出苹果的标签集&#xff0c;所以需要我们自己通过前4问得到训练的标签集&#xff0c;采用的是yolov5 7.0 版本&#xff0c;该版本带分割功能 一&#xff1a;关于数据集的制作&#xff1a; clc; close all; clear; %-----这个是生成yolov5 数据…

2、git进阶操作

2、git进阶操作 2.1.1 分支的创建 命令参数含义git branch (git checkout -b)<new_branch> <old_branch>表示创建分支-d <-D>删除分支 –d如果分支没有合并&#xff0c;git会提醒&#xff0c;-D强制删除-a -v查看分支-m重新命名分支commit id从指定的commi…

【数据结构】树与二叉树(廿二):树和森林的遍历——后根遍历(递归算法PostOrder、非递归算法NPO)

文章目录 5.1 树的基本概念5.1.1 树的定义5.1.2 森林的定义5.1.3 树的术语 5.2 二叉树5.3 树5.3.1 树的存储结构1. 理论基础2. 典型实例3. Father链接结构4. 儿子链表链接结构5. 左儿子右兄弟链接结构 5.3.2 获取结点的算法5.3.3 树和森林的遍历1. 先根遍历&#xff08;递归、非…

XG916Ⅱ轮式装载机后驱动桥设计机械设计CAD

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;装载机 获取完整论文报告工程源文件 本次设计内容为XG916Ⅱ装载机后驱动桥设计&#xff0c;大致上分为主传动的设计&#xff0c;差速器的设计&#xff0c;半轴的设计&#xff0c;最终传动的设计四大部分。其中主传动锥齿轮…

【从删库到跑路】MySQL数据库 — E-R图 | 关系模型

&#x1f38a;专栏【MySQL】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 大一同学小吉&#xff0c;欢迎并且感谢大家指出我的问题&#x1f970; 文章目录 &#x1f339;简述什么是E-R图⭐核心概念 &#x1f339;E-R图…

MTK联发科MT6762/MT6763/MT6765安卓核心板参数规格比较

MT6762安卓核心板 MTK6762安卓核心板是一款工业级高性能、可运行 android9.0 操作系统的 4G智能模块。 CPU&#xff1a;4xCortex-A53 up to 2.0Ghz/4xCortex-A53 up to 1.5GhzGraphics&#xff1a;IMG GE8320 Up to 650MhzProcess&#xff1a;12nmMemory&#xff1a;1xLP3 9…

Windows从源码构建tensorflow(离线编译)

由一开始的在线编译&#xff0c;到后面的离线编译&#xff0c;一路踩坑无数&#xff0c;历经整整6个半小时&#xff0c;终于编译成功&#xff01;在此记录一下参考过的文章&#xff0c;有时间整理一下踩坑记录。 一、环境配置 在tensorflow官网上有版本对应关系 win10 bazel …