React Native中防止滑动过程中误触
React Native中防止滑动过程中误触
在使用React Native开发的时,当我们快速滑动应用的时候,可能会出现误触,导致我们会点击到页面中的某一些点击事件,误触导致页面元素响应从而进行其他操作,表现出非常不好的用户体验。

一、问题背景
常见的情形是长列表中,在滑动过程中可能会出现误触到列表中的某一项的情形,对于用户使用非常不好的体验。
如下列表组件中,就会存在滑动过程中产生误触的情况。
import React from 'react';
import { StyleSheet, Text, SafeAreaView,ScrollView, View, TouchableOpacity, StatusBar,
} from 'react-native';const App = () => {const list = Array.from(Array(100).keys());const onPress = (e) => {alert(1);};return (<SafeAreaView style={styles.container}><ScrollView style={styles.scrollView}>{list.map((item) => {return (<TouchableOpacity onPress={onPress}><View style={styles.containerView}><Text style={styles.text}>{item}+ item</Text></View></TouchableOpacity>);})}</ScrollView></SafeAreaView>);
};const styles = StyleSheet.create({container: { flex: 1, paddingTop: StatusBar.currentHeight },scrollView: { marginHorizontal: 20 },text: { fontSize: 1 },containerView: { backgroundColor: 'pink', marginTop: 20, height: 50 },
});
export default App;
上面长列表,在滚动的过程中可能会出现误触的问题。
二、解决思路
我们应该如何处理这种情形,可以考虑从点击事件上入手,考虑根据距离的移动来进行组织是否响应点击事件
通过查看官方文档,我们能够发现点击时间在点击按下和抬起的过程中有一个过程回调,我们就可以利用这个回调进行处理误触了,有兴趣的小伙伴可以看看这块官方说明
由于点击事件执行过程原理
-
onPressIn 在按压时被调用。
-
onPressOut 在按压动作结束后被调用。
在按下 onPressIn 后,将会出现如下两种情况的一种:用户移开手指,依次触发onPressOut 和onPress事件。
按压持续 500 毫秒以上,触发onLongPress 事件。(onPressOut 在移开手后依旧会触发。)

可以通过监听点击事件的方式来监听按钮点击,那我们来简单实现一个避免误触的方案
其中的核心原理就是点击事件的整个过程,总结来说就是下面的三个点击过程
onPressOut={(event) => {const [startX, startY] = [event.nativeEvent.pageX,event.nativeEvent.pageY,];const currentTime = new Date().getTime();const shouldReject =(Math.abs(pressInPointRef.current.startX - startX) >pointDistance ||Math.abs(pressInPointRef.current.startY - startY) >pointDistance) &&(currentTime - pressInTime.current) < pointMinTimeSpace;console.log('shouldReject', shouldReject);shouldReject && event?.preventDefault?.();}}onPress={(event) => {if (event?.isDefaultPrevented?.()) return;onclick && onclick();}}onPressIn={(event) => {pressInPointRef.current.startX = event.nativeEvent.pageX;pressInPointRef.current.startY = event.nativeEvent.pageY;pressInTime.current = new Date().getTime();}}
当发生触摸时,通过onPressIn事件记录位置和获取事件戳,当指头触摸弹起时,通过onPressOut事件记录并且对比按下时的位置和按下时的时间,是否满足响应当前点击的条件,如果不满足响应,则使用event?.preventDefault?.()阻止其继续响应,最后根据onPress事件中if (event?.isDefaultPrevented?.()) return;判断该如何响应这次触摸点击,这就是整个过程。
-
pressInTime
调整按压时间区间,在按下时和抬起间隔小于该时间,则认为是误触,这个和距离区间(pointDistance)一起确定是否误触 -
pointDistance
调整按下和抬起时之间的距离,在按下时和抬起间隔小于该距离,则认为是误触,这个和按压时间(pressInTime)区间一起确定是否误触 -
调整显示组件
其中TouchableOpacity组件可以更换为能够响应点击事件的任何组件,下面是官方列出的被引用到的组件,都能够使用这种方式处理误触。ButtonPanResponderPressableScrollViewTextTextInputTouchableHighlightTouchableOpacityTouchableNativeFeedbackTouchableWithoutFeedbackView
针对以上情况,能够将其应用到业务不同的误触情况下,下面是整理之后,完整的代码,根据以上情况可以再次进行组件封装,适配自己业务组件的调整。
const App = () => {const list = Array.from(Array(100).keys());const pressInPointRef = useRef({ startX: 0, startY: 0 });const。pressInTime = useRef(0);const pointDistance = 100;const pointMinTimeSpace = 1000;const onclick = () => {console.log('按钮被点击...');alert('按钮被点击...')};return (<SafeAreaView style={styles.container}><ScrollView style={styles.scrollView}>{list.map((item) => {return (<TouchableOpacityonPressOut={(event) => {const [startX, startY] = [event.nativeEvent.pageX,event.nativeEvent.pageY,];const currentTime = new Date().getTime();const shouldReject =(Math.abs(pressInPointRef.current.startX - startX) >pointDistance ||Math.abs(pressInPointRef.current.startY - startY) >pointDistance) &&(currentTime - pressInTime.current) < pointMinTimeSpace;console.log('shouldReject', shouldReject);shouldReject && event?.preventDefault?.();}}onPress={(event) => {if (event?.isDefaultPrevented?.()) return;onclick && onclick();}}onPressIn={(event) => {pressInPointRef.current.startX = event.nativeEvent.pageX;pressInPointRef.current.startY = event.nativeEvent.pageY;pressInTime.current = new Date().getTime();}}><View style={styles.containerView}><Text style={styles.text}>{item}+ line</Text></View></TouchableOpacity>);})}</ScrollView></SafeAreaView>);
};
三、总结整理
- 解决这次触摸,主要是使用点击事件本身的一个响应机制,在中间通过记录状态值的方式去处理
- 使用到的方法涉及到按下时、抬起时、按下这三个过程
- 通用功能组件需要进行封装,以达到业务功能上的适配

相关文章:
React Native中防止滑动过程中误触
React Native中防止滑动过程中误触 在使用React Native开发的时,当我们快速滑动应用的时候,可能会出现误触,导致我们会点击到页面中的某一些点击事件,误触导致页面元素响应从而进行其他操作,表现出非常不好的用户体验。 一、问题…...
【c语言】函数递归调用
创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!! 主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步! 给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ…...
SPSS如何进行判别分析之案例实训?
文章目录 0.引言1.一般判别分析2.逐步判别分析3.决策树分析 0.引言 因科研等多场景需要进行绘图处理,笔者对SPSS进行了学习,本文通过《SPSS统计分析从入门到精通》及其配套素材结合网上相关资料进行学习笔记总结,本文对判别分析进行阐述。 1…...
Windows 10 字体模糊发虚的问题及解决方法
Windows 10字体模糊发虚! 如何解决?Windows 10是一款常见的操作系统,它拥有各种各样的功能,但是有些用户发现,在使用Windows 10时,字体会变得模糊发虚,这给用户带来了很多不便。下面,我们就来看看如何解决…...
渔人杯部分wp
文章目录 渔人杯神仙姐姐阿拉丁飘啊飘 渔人杯 神仙姐姐 点击拜 ,抓包发现get请求了/sx.php 返回如下 {"code":0,"num":1,"flag":"ctfsh0w-f1ag-n0t-h3r3-th1s-msg-just-a-j0ke-}{"}在repeater重复请求,发现…...
测试用例覆盖不全面的解决方法
测试用例覆盖不全面的解决方法 问题分析 在测试用例设计过程中,容易出现思维受限或者需求盲区,我们不可能完全覆盖用户使用的所有场景,编写测试用例的时不可能把所有的场景都能想周全,把所有的场景下的情况都写成测试用例去模拟、…...
AWS Lambda - 第一部分
Hello大家好,我们今天开始讨论AWS Lambda的内容。 SAP认证考试会涉及到很多Lambda的内容,想要通过认证考试虽然不一定非要精通开发,但需要知道Lambda的一些功能和特性、适用场景以及Lambda是如何工作的。 我们开始吧! Lambda与…...
Java 基础进阶篇(七)—— 面向对象三大特征之三:多态
文章目录 一、多态的概述二、多态中成员访问特点 ★三、多态的优势与劣势四、多态下的类型转换4.2 自动类型转换(从子到父)4.2 强制类型转换(从父到子)4.3 instanceof 关键字 一、多态的概述 多态:是指执行同一个行为…...
day9 实现UDP通信
目录 socket函数拓展 UDP通信实现过程 代码实现 socket函数拓展 send与recv函数: /*用于发送数据*/ ssize_t send(int sockfd, const void *buf, size_t len,int flags);/*用于接收数据*/ ssize_t recv(int sockfd, void *buf, size_t len,int flags);/*前三个…...
自然语言处理(NLP)在放射学报告评价中的应用:应用和技术进展
自然语言处理(NLP)在放射学报告评价中的应用:应用和技术进展 写在最前面摘要引言先进的技术BERT算法优点 Applications in Radiology 放射学应用Quality 质量将关键发现通知转诊临床医生放射科关键绩效指标和评估 个别放射科医生的表现同行学…...
日常开发为什么需要做Code Review
日常开发为什么需要做Code Review 一、背景 最近在开始一个新的项目,在查看项目中代码及具体细节时,发现这个项目真实一堆乱麻,没有规律可循,可总结下这个项目的缺陷 没有规律可循,没有结构性设计不做公共封装&#…...
OSPF的优化
O_ASE --- 标志域外路由信息 --- 因为域外的路由信息不可控性较强,所以,信任程度较低,我们将其优先级设置为150。 LSA --- 链路状态通告 --- OSPF协议在不同网络环境下产生的用于携带和传递不同的信息。 LSDB --- 链路状态数据库 SPF --- 最短…...
C++项目中打破循环依赖的锁链:实用方法大全
C项目中打破循环依赖的锁链 一、简介(Introduction)1.1 循环依赖的定义(Definition of Circular Dependencies)1.2 循环依赖带来的问题(Problems Caused by Circular Dependencies)1.3 解决循环依赖的重要性…...
IDEA连接HBase
新建maven工程 打开pom.xml添加hbase需要的依赖 <dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>2.3.5</version> </dependency><dependency><groupId>org.apa…...
Mask2Former来了!用于通用图像分割的 Masked-attention Mask Transformer
原理https://blog.csdn.net/bikahuli/article/details/121991697 源码解析 论文地址:http://arxiv.org/abs/2112.01527 项目地址:https://bowenc0221.github.io/mask2former Mask2Former的整体架构由三个组件组成: 主干特征提取器ÿ…...
【量化课程】01_投资与量化投资
文章目录 1.1 什么是投资1.1.1 经济意义上的投资1.1.2 投资的分类1.1.3 金融投资1.1.4 个人投资者投资品种1.1.5 投资VS投机 1.2 股票投资的基本流程1.3 常见的股票投资分析流派1.3.1 投资者分析流派 1.4 什么是量化投资1.4.1 量化投资基本概念1.4.2 量化投资的优势1.4.3 量化投…...
SpringBoot实现导出Excel功能
1 问题背景 需求要做一个导出excel的功能 2 前言 本篇着重阐述后端怎么实现,前端实现的部分只会粗略阐述。该实现方案是经过生产环境考验的,不是那些拿来练手的小demo。本文阐述的方案可以借鉴用来做毕设或者加到自己玩的项目中去。再次声明,…...
NSSCTF之Misc篇刷题记录⑧
NSSCTF之Misc篇刷题记录 [MMACTF 2015]welcome[广东强网杯 2021 团队组]欢迎参加强网杯[虎符CTF 2022]Plain Text[SWPUCTF 2021 新生赛]原来你也玩原神[SWPUCTF 2021 新生赛]我flag呢?[鹤城杯 2021]New MISC NSSCTF平台:https://www.nssctf.cn/ PS&…...
从零开始学习Linux运维,成为IT领域翘楚(七)
文章目录 🔥Linux下常用软件安装_JDK和Tomcat安装🔥Linux下常用软件安装_MySQL安装🔥Linux下常用软件安装_MySQL卸载 🔥Linux下常用软件安装_JDK和Tomcat安装 Jdk 安装 解压jdk安装包 tar -zxvf jdk-8u201-linux-x64.tar.gz -C/…...
优漫动游设计APP的UI界面需要注意哪些问题?
一、加载 加载时间的长短,很大程度的决定了用户体验是否有所提升,虽然理想中的页面加载出来应该一秒就够了,但是设计师不要忽略网络问题!如果网速不够的话,页面加载三五秒都算是快的了,所以在用户等待的过程中&a…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
