阻止 mousemove 或 touchmove 与 click 事件同时触发

news/2024/5/4 11:15:52/文章来源:https://blog.csdn.net/tiven_/article/details/127532616

最近做了自己的开源项目 Msw-Tools,参考了 VConsole 工具中按钮的拖拽功能,计划给 MSW 按钮也增加类似的拖拽效果,并兼容PC端和手机端,但是遇到一个问题:一个按钮绑定了多个事件,怎样才能阻止 mousemove 或 touchmove 与 click 事件同时触发

MSW Tools

一、背景

如上图所示,实现 MSW 按钮拖拽要用到 mousedown、mousemove、mouseup 事件,对应的移动端要用到 touchstart、touchmove、touchend 事件,但是按钮上已经绑定了 click 点击事件,所以就要想办法阻止 mouse 鼠标事件或 touch 触摸事件 与 click 事件同时触发。不然每次拖拽按钮后都会触发 click 事件,这显然是不友好的。

二、问题解析

事件的执行顺序依次是:mousedown > mousemove > mouseup > click,因此,要想 mouseup 事件执行完后,不执行 click 事件,可能不太好直接处理,但是可以间接的实现。设置一个 移动状态的开关,并加上 延迟处理 就可以达到"阻止 click 事件"的目的。

三、代码实现

因为 Msw-Tools 工具是使用 Svelte 框架开发的,所以这里展示 Svelte 部分代码。

<!-- msw.svelte --><div class="msw-container"><div on:click|stopPropagation={showModal}bind:this={btnDOM}class="msw-show">MSW</div>
</div><script>import { onMount } from "svelte";// 区分当前是PC端,还是移动端,来设置 mouse 事件 或 touch 事件function getModels() {let userAgentInfo = navigator.userAgent;let mobileAgents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];return mobileAgents.reduce((prev, ua)=>{return userAgentInfo.includes(ua) || prev}, false)};const MSW_BTN_POSITION = '__MSW_BTN_POSITION__'let show = false;let btnDOM = null;let isDrop = false;let isMoving = false;let offset = {x: 0,y: 0,};let offsetDown = {};let dropTimer = null;let isMobile = getModels();let btnW = 0;let btnH = 0;let clientW = 0;let clientH = 0;let eventType = isMobile ? 'touchstart' : 'mousedown';// DOM 挂载后执行onMount(async () => {// 初始化,获取按钮、视口宽高、计算边界值initClientData();return () => {// component 卸载后,解除事件绑定btnDOM.removeEventListener(eventType, btnMousedown)}});function initClientData() {// 按钮位置保存在本地,可以记住位置,避免每次去拖拽let local = localStorage.getItem(MSW_BTN_POSITION)if (local) {offset = JSON.parse(local)btnMove()}let w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidthclientW = isMobile ? w : document.body.clientWidthclientH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeightbtnW = btnDOM.offsetWidthbtnH = btnDOM.offsetHeight// 给按钮绑定 mousedown 或 touchstart 事件btnDOM.addEventListener(eventType, btnMousedown)}function eventHandle (type) {if (isMobile) {document[`${type}EventListener`]('touchmove', mousemove);document[`${type}EventListener`]('touchend', mouseup);} else {document[`${type}EventListener`]('mousemove', mousemove);document[`${type}EventListener`]('mouseup', mouseup);}}function showModal () {if (!isMoving) {show = true;}}function btnMousedown(e) {e = e || window.eventisDrop = trueoffsetDown = {...getOffset(e)};eventHandle('add')}function mousemove(e) {e = e || window.eventif (isDrop) {let data = getOffset(e);// 判断是否移动了isMoving = !(offsetDown.x === data.x && offsetDown.y === data.y)let x = data.x - btnW / 2;let y = data.y - btnH / 2;if (x > 5 && x < (clientW-btnW - 5)) {offset.x = x;}if (y > 5 &&  y < (clientH-btnH - 5)) {offset.y = y;}if (isMoving) {btnMove()}clearTimeout(dropTimer);dropTimer = setTimeout(()=>{isMoving = false;clearTimeout(dropTimer);dropTimer = null;}, 300);}}function mouseup() {if (isDrop) {window.localStorage.setItem(MSW_BTN_POSITION, JSON.stringify(offset))eventHandle('remove')}isDrop = false// console.log('mouseup')}function btnMove (){btnDOM.style.cssText = `left: ${offset.x}px;top: ${offset.y}px;right: auto;bottom: auto;`}function getOffset(e) {return isMobile ? {x: e.targetTouches[0].clientX,y: e.targetTouches[0].clientY,} : {x: e.clientX,y: e.clientY,}}
</script><style lang="scss" type="text/scss">@import "index";
</style>
  • 效果体验:msw-tools

欢迎访问:天问博客

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

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

相关文章

Python还能这样玩?让你轻松实现配色自由

嗨嗨&#xff0c;你们好 好几天没更新了&#xff0c;最近有点点无聊&#xff0c;就琢磨出一个一个有趣的东西 教你们用python快速获取图片配色&#xff0c;做个可视化配色方案出来 这期分享一个Python快速提取任何图片配色方案的工具&#xff1a;Haishoku Haishoku是一个用来…

概论相关分布知识--回顾笔记

伯努利分布&#xff1a;如果变量X服从伯努利分布 Ber(p) &#xff0c;那么 X只有两种取值&#xff0c;记为{0,1}&#xff0c;有&#xff1a;二项分布&#xff1a;如果变量X服从二项分布B(n,p) &#xff0c;那么X有 n 1 种取值&#xff0c;有&#xff1a;categorical 分布&…

Android靶场All Safe 靶场WP

环境准备 ADB DDMS ALLsafe app part 1 不安全的日志记录 挑战 在不反编译的情况下从日志中获取输入的密钥。 方法一 使用DDMS监控日志记录&#xff0c;工具在SDK/tools目录下的monitor.bat&#xff0c;需要java8的环境支持&#xff0c;java11会报错。 使用adb连接 测试机…

工业控制系统安全评估流程物理环境脆弱性

架构与设计脆弱性 表 4.2 架构与设计脆弱性检查表 脆弱性 描述 安全架构是企业架构的一部分&#xff0c;在工业控制系统 架构设计之初&#xff0c;应该融合考虑。 在架构搭建与设计过程中未考虑安全因素 在架构设计时需要解决用户识别与授权、访问控制机 制实现、网络拓扑绘制…

厨电智能化趋势下,究竟什么才是真正的“用户思维”?

文|智能相对论 作者|佘凯文 近期2022年前三季度的各项经济数据在陆续发布&#xff0c;大环境依然承压&#xff0c;各个行业都在负重前行。 厨电行业在房地产下滑、疫情反复等因素影响下&#xff0c;前三季度同样一直承受着不小的压力&#xff0c;AVC数据显示&#xff0c;202…

进程的创建终止、阻塞唤醒、挂起激活(操作系统)

目录 一、引起创建进程的事件 二、进程的创建 三、进制的终止 1&#xff0e;引起进程终止的事件 2&#xff0e;进程的终止过程 四、进程的阻塞和唤醒 1&#xff0e;引起进程阻塞和唤醒的事件 2&#xff0e;进程阻塞过程 3&#xff0e;进程唤醒过程 五、进程的挂起和激活 1&…

安装Mysql-zip安装

一、安装 1、下载 到mysql官网 http://dev.mysql.com/downloads/mysql/ 下载mysql 注:msi的是安装版 2、解压 解压到想安装的目录下,我的是D:mysql-5.7.13-winx64 3、配置my.ini 在D:mysql-5.7.13-winx64目录下新建my.ini文件,输入以下配置代码: [mysqld] port = 3306 base…

springboot嘉应房地产公司质量管理系统毕业设计源码453100

目 录 摘要 1 1 绪论 1 1.1研究背景及意义 1 1.2国内外研究现状及发展趋势 1 1.3系统开发技术的特色 1 1.4论文结构与章节安排 1 2 嘉应房地产公司质量管理系统 系统分析 3 2.1 可行性分析 3 2.2 系统流程分析 3 2.2.1数据增加流程 3 2.3.2数据修改流程 4 2.3.3数据删除流程 4…

Python提取pdf中的表格数据(附实战案例)

14天阅读挑战赛 今天给大家介绍一个Python使用工具&#xff0c;那就是从pdf文件中读取表格数据&#xff0c;主要用到第三方库 pdfplumber。 pdfplumber简介 pdfplumber是一款基于pdfminer&#xff0c;完全由python开发的pdf文档解析库&#xff0c;不仅可以获取每个字符、矩形…

[spark]transformation算子

1.sample算子 1&#xff09;说明 sample算子&#xff1a;对rdd中的数据进行抽样。一个非常重要的作用就是开看rdd中数据的分布&#xff0c;进行各种调优与优化。 数据倾斜&#xff1a;数据分布的不均匀&#xff0c;shuffle会将相同key的数据汇总到一台机器上&#xff0c;就会…

水库水雨情监测系统 水雨情自动测控平台 水库雨水情监测及视频监控解决方案_设备_水位_远程

平升电子水库水雨情监测系统 水雨情自动测控平台 水库雨水情监测及视频监控解决方案_设备_水位_远程辅助水利管理部门实现水库雨水情信息“全要素、全量程、全覆盖”自动测报。系统具备水库水位、雨量、现场图像/视频等水文信息采集、传输、处理及预警广播等功能&#xff0c;有…

12-敏感的资料怎么存在K8S-Secret

12-敏感的资料怎么存在K8S-Secret 前言 今天的学习笔记将介绍Kubernetes另一个组件secret。secret协助开发者将一些敏感信息&#xff0c;像是数据库账密、访问其它server的access token、ssh key&#xff0c;用非明文的方式&#xff08;opaque&#xff09;存放在Kubernetes中…

【数据结构与算法分析】0基础带你学数据结构与算法分析06--树(TREE)

目录 前言 树的属性 树的实现 树的遍历与应用 深度有限遍历 (DFS) 广度优先遍历 (BFS) Not all roots are buried down in the ground, some are at the top of a tree. — Jinvirle 前言 Tree 是一些结点的集合&#xff0c;这个集合可以是空集&#xff1b;若不是空集…

中国锚杆行业竞争格局及投资风险分析报告

锚杆的概念 锚杆(又称土锚杆、土钉)是在天然土层侧壁钻孔&#xff0c;放置拉杆&#xff0c;注浆锚固而成。根据所用材料&#xff0c;拉杆可分为粗钢筋、高强度钢丝束、钢绞线等。通过计算确定了侧墙上锚杆的截面积、层数、间距和长度。钻孔直径应由设计确定。常用的孔道灌浆有水…

【QT + OsgEarth】(四)加载国界线矢量图

效果图 实现过程 获取国界线矢量图在.earth文件中加载矢量图文件在Qt程序中获取图层节点并控制参数 加载矢量图文件 < image > 标签定义要栅格化的shp文件 driver&#xff1a;使用agglite&#xff0c;将矢量文件栅格成为栅格文件< features > 子标签读取shp文件…

亿可控_第3章 指标数据持久化与设备详情展示

亿可控_第3章 指标数据持久化与设备详情展示 文章目录亿可控_第3章 指标数据持久化与设备详情展示第3章 指标数据持久化与设备详情展示学习目标1. InfluxDB入门及介绍1.1 InfluxDB简介1.2 InfluxDB相关概念1.3 InfluxDB的基本操作1.3.1 InfluxDB数据库操作1.3.2 InfluxDB数据表…

SANGFOR深信服短信插件

设置说明 第一步&#xff1a;先配置短信通知服务器&#xff08;以下以HTTP为例&#xff09;。 步骤1、设置短信通知服务器&#xff0c;在[系统管理/系统配置/高级配置/通知设置]&#xff0c;点击<新增短信通知服务器>&#xff0c;勾选启用&#xff0c;可启用短信通知服…

mdio bcm5482访问

查看硬件原理图&#xff0c;5482通过mdio访问自己的寄存器&#xff0c;M4通过cpld对5482进行初始化操作(复位/解复位&#xff09; 可以看到bcm5482的MDC和MDIO用的是port P 的pin4和pin5,所以基地址为GPIO_PORTP_BASE. 对应的分别是引脚4和引脚5&#xff0c;所以由此可以封装出…

SHEIN算法工程师面试题7道|含解析

8本电子书免费送给大家&#xff0c;见文末。 1、数据处理的常用方法有哪些&#xff1f; 对于离群点 当作缺失值进行处理删掉离群点所在的样本实用统计值进行填充 对于缺失值 可以用均值或均位数进行填充可以用特定值&#xff0c;如-1可以用np.nan表示 对于类别特征 编码方…

SPI示例学习

Service Provider Interface 它是从Java 6开始引入的&#xff0c;是一种基于ClassLoader来发现并加载服务的机制。 服务发现机制&#xff1a;通过在ClassPath路径下的META-INFO/services文件夹中查找文件&#xff0c;并自动加载文件里所定义的类。 SPI机制可以很好的解决不同…