[英]How do I recognize swipe events in React?
I'm currently developing a React app and I want to detect swipe events (left, right) on a div
element (on mobile devices).我目前正在开发一个 React 应用程序,我想检测
div
元素(在移动设备上)上的滑动事件(左、右)。
How do I achieve this without any additional libraries?我如何在没有任何额外库的情况下实现这一目标?
@gru's code works great, the only downside is that it also detects a swipe when the user tries to scroll down and moves slightly to the side as well. @gru 的代码运行良好,唯一的缺点是当用户尝试向下滚动并稍微向侧面移动时,它也会检测到滑动。
My changes makes sure the swipe is only detected when the horizontal movement is greater than the vertical movement:我的更改确保仅当水平移动大于垂直移动时才检测到滑动:
const distanceX = touchStartX - touchEndX
const distanceY = touchStartY - touchEndY
const isLeftSwipe = distanceX > minSwipeDistance
const isRightSwipe = distanceX < -minSwipeDistance
if (isRightSwipe && Math.abs(distanceX) > distanceY) {
// add your conditional logic here
}
if (isLeftSwipe && distanceX > distanceY) {
// add your conditional logic here
}
This code detects left and right swipe events, without having any impact on usual touch events.此代码检测左右滑动事件,对通常的触摸事件没有任何影响。
const [touchStart, setTouchStart] = useState(null)
const [touchEnd, setTouchEnd] = useState(null)
// the required distance between touchStart and touchEnd to be detected as a swipe
const minSwipeDistance = 50
const onTouchStart = (e) => {
setTouchEnd(null) // otherwise the swipe is fired even with usual touch events
setTouchStart(e.targetTouches[0].clientX)
}
const onTouchMove = (e) => setTouchEnd(e.targetTouches[0].clientX)
const onTouchEnd = () => {
if (!touchStart || !touchEnd) return
const distance = touchStart - touchEnd
const isLeftSwipe = distance > minSwipeDistance
const isRightSwipe = distance < -minSwipeDistance
if (isLeftSwipe || isRightSwipe) console.log('swipe', isLeftSwipe ? 'left' : 'right')
// add your conditional logic here
}
<div onTouchStart={onTouchStart} onTouchMove={onTouchMove} onTouchEnd={onTouchEnd}/>
If you need to detect vertical swipes as well (up and down), you can use e.targetTouches[0].clientY
(see docs ) in a similar manner.如果您还需要检测垂直滑动(向上和向下),您可以以类似的方式使用
e.targetTouches[0].clientY
(请参阅 文档)。
Excellent solution provided by @gru. @gru 提供的优秀解决方案。 I just encapsulated it into a custom hook to be simpler to integrate between different components.
我只是将它封装到一个自定义挂钩中,以便更简单地在不同组件之间进行集成。
useSwipe.tsx使用滑动.tsx
import {TouchEvent, useState} from "react";
interface SwipeInput {
onSwipedLeft: () => void
onSwipedRight: () => void
}
interface SwipeOutput {
onTouchStart: (e: TouchEvent) => void
onTouchMove: (e: TouchEvent) => void
onTouchEnd: () => void
}
export default (input: SwipeInput): SwipeOutput => {
const [touchStart, setTouchStart] = useState(0);
const [touchEnd, setTouchEnd] = useState(0);
const minSwipeDistance = 50;
const onTouchStart = (e: TouchEvent) => {
setTouchEnd(0); // otherwise the swipe is fired even with usual touch events
setTouchStart(e.targetTouches[0].clientX);
}
const onTouchMove = (e: TouchEvent) => setTouchEnd(e.targetTouches[0].clientX);
const onTouchEnd = () => {
if (!touchStart || !touchEnd) return;
const distance = touchStart - touchEnd;
const isLeftSwipe = distance > minSwipeDistance;
const isRightSwipe = distance < -minSwipeDistance;
if (isLeftSwipe) {
input.onSwipedLeft();
}
if (isRightSwipe) {
input.onSwipedRight();
}
}
return {
onTouchStart,
onTouchMove,
onTouchEnd
}
}
can be integrated in different components like this可以像这样集成在不同的组件中
import useSwipe from "whatever-path/useSwipe";
const swipeHandlers = useSwipe({ onSwipedLeft: () => console.log('left'), onSwipedRight: () => console.log('right') });
<div {...swipeHandlers}>some swipeable div (or whatever html tag)</div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.