0

0

react怎么实现滑动

藏色散人

藏色散人

发布时间:2022-12-30 11:09:00

|

2356人浏览过

|

来源于php中文网

原创

react实现滑动的方法:1、在onTouchStart事件找到touches,根据identifier中记录新的touch出现;2、在onTouchMove事件中根据identifier来记录每个touch经过的点的坐标;3、在onTouchEnd事件中,找到结束的touch事件,然后通过结束的touch事件划过的点来计算要执行的手势即可。

react怎么实现滑动

本教程操作环境:Windows10系统、react18.0.0版、Dell G3电脑。

react怎么实现滑动?

react 实现左右滑动效果

React 中滑动手势的实现

35ad8859e3a5ad94b0e23e5210bd91d5.png

最近做了一点关于react在移动端滑动翻页的功能。

开始搜索了一下,发现居然没找到合适的库,唯一找到了名字叫react-touch的库,一看,前端世界四五百star===自己撸,而且似乎也不是想要的功能,算了自己写点吧。

看了下原理,基本就是配合onTouchStart,onTouchMove和onTouchEnd这三个事件,来记录滑动过的点,然后来计算手势。

显然对于多点触摸,需要找到每个点触摸的路径,所以有如下几步:

  • 在onTouchStart事件找到touches,根据identifier中记录新的touch出现。

  • 在onTouchMove事件中根据identifier来记录每个touch经过的点的坐标。

  • 在onTouchEnd事件中,找到结束的touch事件,然后通过结束的touch事件划过的点来计算要执行的手势。

对于我来说我只是想要上下滑动的功能那么我就只关注单点触摸的情况。

接下来准备上代码。哦,不对,首先要想想要怎么封装。开始自问自答:

我想用一个单例模式。

是不是使用有点太麻烦了,还要先实例化一下?

jquery实现的滑动解锁
jquery实现的滑动解锁

jquery实现的滑动解锁

下载

那用静态类?

都js了还要啥静态类,输出个字典完事。

那好吧,开始撸吧。

数据部分

const touchData = { touching: false, trace: [] };
// 单点触摸,所以只要当前在触摸中,就可以把划过的点记录到trace中了
function* idGenerator() {
  let start = 0;
  while (true) {
    yield start;
    start += 1;
  }
}
//这个生成器用来生成不同事件回调的id,这样我们可以注册不同的回调,然后在不需要的时候删掉。
const callbacks = {
  onSlideUpPage: { generator: idGenerator(), callbacks: {} },
  onSlideDownPage: { generator: idGenerator(), callbacks: {} }
};
//存储向上、下换页的回调函数

记录触摸部分

这里的事件处理的是react的合成事件,并非原生事件。

function onTouchStart(evt) {
  if (evt.touches.length !== 1) {
    touchData.touching = false;
    touchData.trace = [];
    return;
  }
  touchData.touching = true;
  touchData.trace = [{ x: evt.touches[0].screenX, y: evt.touches[0].screenY }];
}
//在onTouchStart事件,如果是多点触摸直接清空所有数据。如果是单点触摸,记录第一个点,并设置状态
function onTouchMove(evt) {
  if (!touchData.touching) return;
  touchData.trace.push({
    x: evt.touches[0].screenX,
    y: evt.touches[0].screenY
  });
}
//如果在单点触摸过程中,持续记录触摸的位置。
function onTouchEnd() {
  if (!touchData.touching) return;
  let trace = touchData.trace;
  touchData.touching = false;
  touchData.trace = [];
  handleTouch(trace);  //判断touch类型并调用适当回调
}
//在触摸结束事件,中调用handleTouch函数来处理手势判断逻辑并执行回调

handleTouch函数

function handleTouch(trace) {
  let start = trace[0];
  let end = trace[trace.length - 1];
  if (end.y - start.y > 200) {
    Object.keys(callbacks.onSlideUpPage.callbacks).map(key =>
      callbacks.onSlideUpPage.callbacks[key]()
    ); 
    // 向上翻页
  } else if (start.y - end.y > 200) {
    Object.keys(callbacks.onSlideDownPage.callbacks).map(key =>
      callbacks.onSlideDownPage.callbacks[key]()
    );
    // 向下翻页
  }
}

在这里我只判断了向上向下翻页两个事件,如果事件达成,则会调用所有注册到该事件的回调。如果有多个回调可按照需求对回调的执行顺序进行调整。这里应该是无序的。

接口部分

function addSlideUpPage(f) {
  let key = callbacks.onSlideUpPage.generator.next().value;
  callbacks.onSlideUpPage.callbacks[key] = f;
  return key;
}
//注册向上滑动回调并返回回调id
function addSlideDownPage(f) {
  let key = callbacks.onSlideDownPage.generator.next().value;
  callbacks.onSlideDownPage.callbacks[key] = f;
  return key;
}
//注册向下滑动回调并返回回调id
function removeSlideUpPage(key) {
  delete callbacks.onSlideUpPage.callbacks[key];
}
//使用回调id删除向上滑动回调
function removeSlideDownPage(key) {
  delete callbacks.onSlideDownPage.callbacks[key];
}
//使用回调id删除向下滑动回调
export default {
  onTouchEnd,
  onTouchMove,
  onTouchStart,
  addSlideDownPage,
  addSlideUpPage,
  removeSlideDownPage,
  removeSlideUpPage
};
//输出所有接口函数

这没啥说的,就是折麽简单粗暴。接下来,就在react中使用吧!

在next.js中使用

我使用的next.js+create-next-app。在pages目录下的_app.js文件中绑定所有touch事件。

//pages/_app.js
import App, { Container } from "next/app";
import React from "react";
import withReduxStore from "../redux/with-redux-store";
import { Provider } from "react-redux";
import touch from "../components/touch";

class MyApp extends App {
  render() {
    const { Component, pageProps, reduxStore } = this.props;
    return (
      
        
          
{ // 将所有导出的touch事件绑定在最外层的div上 // 这样就可以全局注册事件了 }
); } } export default withReduxStore(MyApp);

接下来看看如何使用。

import React, {useEffect} from "react";
import touch from "../touch";

const Example = () => {
  useEffect(() => {
    let key = touch.addSlideDownPage(() => {
      console.log("try to slideDownPage!!")
    });
    return () => {
      touch.removeSlideDownPage(key)
      // 用完别忘了删除事件
    };
  }, []);
  return (
    
This is an example!!
); };

在原生react中使用

这个项目使用create-react-app生成的

//src/App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';
import touch from "./components/touch";

function App() {
  return (
    
@@##@@

Edit src/App.js and save to reload.

Learn React
); }

结语

如果真的有人仔细看了代码,可能会有个问题,这个touch.js里的内容除了使用了react的合成事件,然后就没react什么事了,好像不太常规。

的确是这样,就没关react什么事了。解释就是这些数据不用通过react的state或者redux的state太传递,一来是在性能上,一更新redux或者react的state就会触发react的重新渲染,没有必要,二就是希望可以全局使用这些接口,所以就并没有借助react的机制。其实这就像是react所说的uncontrolled components。

最后附上完整的touch.js

//touch.js
const touchData = { touching: false, trace: [] };

function* idGenerator() {
  let start = 0;
  while (true) {
    yield start;
    start += 1;
  }
}

const callbacks = {
  onSlideUpPage: { generator: idGenerator(), callbacks: {} },
  onSlideDownPage: { generator: idGenerator(), callbacks: {} }
};

function onTouchStart(evt) {
  if (evt.touches.length !== 1) {
    touchData.touching = false;
    touchData.trace = [];
    return;
  }
  touchData.touching = true;
  touchData.trace = [{ x: evt.touches[0].screenX, y: evt.touches[0].screenY }];
}
function onTouchMove(evt) {
  if (!touchData.touching) return;
  touchData.trace.push({
    x: evt.touches[0].screenX,
    y: evt.touches[0].screenY
  });
}
function onTouchEnd() {
  if (!touchData.touching) return;
  let trace = touchData.trace;
  touchData.touching = false;
  touchData.trace = [];
  handleTouch(trace);
}
function handleTouch(trace) {
  let start = trace[0];
  let end = trace[trace.length - 1];
  if (end.y - start.y > 200) {
    Object.keys(callbacks.onSlideUpPage.callbacks).map(key =>
      callbacks.onSlideUpPage.callbacks[key]()
    );
  } else if (start.y - end.y > 200) {
    Object.keys(callbacks.onSlideDownPage.callbacks).map(key =>
      callbacks.onSlideDownPage.callbacks[key]()
    );
  }
}
function addSlideUpPage(f) {
  let key = callbacks.onSlideUpPage.generator.next().value;
  callbacks.onSlideUpPage.callbacks[key] = f;
  return key;
}
function addSlideDownPage(f) {
  let key = callbacks.onSlideDownPage.generator.next().value;
  callbacks.onSlideDownPage.callbacks[key] = f;
  return key;
}
function removeSlideUpPage(key) {
  delete callbacks.onSlideUpPage.callbacks[key];
}
function removeSlideDownPage(key) {
  delete callbacks.onSlideDownPage.callbacks[key];
}
export default {
  onTouchEnd,
  onTouchMove,
  onTouchStart,
  addSlideDownPage,
  addSlideUpPage,
  removeSlideDownPage,
  removeSlideUpPage
};

推荐学习:《react视频教程

react怎么实现滑动

相关专题

更多
菜鸟裹裹入口以及教程汇总
菜鸟裹裹入口以及教程汇总

本专题整合了菜鸟裹裹入口地址及教程分享,阅读专题下面的文章了解更多详细内容。

0

2026.01.22

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

56

2026.01.21

三角洲入口地址合集
三角洲入口地址合集

本专题整合了三角洲入口地址合集,阅读专题下面的文章了解更多详细内容。

51

2026.01.21

AO3中文版入口地址大全
AO3中文版入口地址大全

本专题整合了AO3中文版入口地址大全,阅读专题下面的的文章了解更多详细内容。

397

2026.01.21

妖精漫画入口地址合集
妖精漫画入口地址合集

本专题整合了妖精漫画入口地址合集,阅读专题下面的文章了解更多详细内容。

118

2026.01.21

java版本选择建议
java版本选择建议

本专题整合了java版本相关合集,阅读专题下面的文章了解更多详细内容。

3

2026.01.21

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

11

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 9.1万人学习

Vue 教程
Vue 教程

共42课时 | 7万人学习

Go 教程
Go 教程

共32课时 | 4.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号