Maison  >  Article  >  interface Web  >  Comment implémenter le glissement en réaction

Comment implémenter le glissement en réaction

藏色散人
藏色散人original
2022-12-30 11:09:002106parcourir

Comment implémenter le glissement dans React : 1. Rechercher les touches dans l'événement onTouchStart et enregistrer l'apparition de nouvelles touches en fonction de l'identifiant ; 2. Enregistrez les coordonnées de chaque point passé par le toucher en fonction de l'identifiant dans l'événement onTouchMove ; 3. Dans l'événement onTouchEnd, recherchez l'événement tactile de fin, puis calculez le geste à effectuer en fonction du point traversé par l'événement tactile de fin.

Comment implémenter le glissement en réaction

L'environnement d'exploitation de ce tutoriel : système Windows 10, React version 18.0.0, ordinateur Dell G3.

Comment implémenter le glissement en réaction ?

react réalise l'effet de glissement gauche et droit

Implémentation de gestes de glissement dans React

Comment implémenter le glissement en réaction

Récemment, j'ai fait un peu sur la fonction de rotation de page coulissante de React sur le terminal mobile.

J'ai commencé à chercher et j'ai découvert que je ne trouvais pas de bibliothèque appropriée. La seule bibliothèque que j'ai trouvée était une bibliothèque nommée React-Touch. À première vue, j'ai découvert qu'il y avait quatre à cinq cents étoiles dans le monde front-end. === moi-même, et cela ne semblait pas être la fonction que je voulais. Oubliez ça, écrivez-en vous-même.

Après avoir regardé le principe, cela fonctionne essentiellement avec les trois événements onTouchStart, onTouchMove et onTouchEnd pour enregistrer le point de glissement puis calculer le geste.

Évidemment pour le multi-touch, vous devez trouver le chemin de chaque point de contact, il y a donc les étapes suivantes :

  • Trouvez les touches dans l'événement onTouchStart, et enregistrez la nouvelle occurrence de contact en fonction de l'identifiant.

  • Dans l'événement onTouchMove, enregistrez les coordonnées de chaque point passé par le toucher en fonction de l'identifiant.

  • Dans l'événement onTouchEnd, recherchez l'événement tactile de fin, puis calculez le geste à effectuer par le point traversé par l'événement tactile de fin.

Pour moi, je veux juste la fonction de glisser de haut en bas, donc je me concentre uniquement sur la situation d'une seule touche.

Ensuite, préparez-vous à écrire le code. Oh non, nous devons d’abord réfléchir à la manière de l’encapsuler. Commencez à vous demander et à répondre :

Je souhaite utiliser un modèle singleton.

Est-ce trop difficile à utiliser ? Dois-je d'abord l'instancier ?

Alors utiliser des classes statiques ?

Si vous avez déjà js, de quelles classes statiques supplémentaires avez-vous besoin? Il suffit de générer un dictionnaire et c'est tout.

D'accord, commençons à nous masturber.

Partie données

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: {} }
};
//存储向上、下换页的回调函数

Partie tactile d'enregistrement

Les événements ici gèrent les événements synthétiques de réaction, pas les événements natifs.

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函数来处理手势判断逻辑并执行回调

fonction 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]()
    );
    // 向下翻页
  }
}

Ici, je ne juge que deux événements, page haut et bas. Si l'événement est atteint, tous les rappels enregistrés pour l'événement seront appelés. S'il y a plusieurs rappels, l'ordre d'exécution des rappels peut être ajusté selon les besoins. Il ne devrait y avoir aucun ordre ici.

Partie interface

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
};
//输出所有接口函数

Il n'y a pas grand chose à dire, c'est tellement simple et grossier. Ensuite, utilisons-le en réaction !

En utilisant

dans next.js, j'utilise next.js+create-next-app. Liez tous les événements tactiles dans le fichier _app.js dans le répertoire pages.

//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 (
      <Container>
        <Provider store={reduxStore}>
          <div
            onTouchEnd={touch.onTouchEnd}
            onTouchStart={touch.onTouchStart}
            onTouchMove={touch.onTouchMove}
          >
            <Component {...pageProps} />
          </div> 
{
// 将所有导出的touch事件绑定在最外层的div上
// 这样就可以全局注册事件了
}
        </Provider>
      </Container>
    );
  }
}

export default withReduxStore(MyApp);

Voyons comment l'utiliser ensuite.

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 (
    <div>This is an example!!</div>
  );
};

Utilisé dans React natif

Ce projet est généré à l'aide de create-react-app

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

function App() {
  return (
    <div className="App"
      onTouchEnd={touch.onTouchEnd}
      onTouchStart={touch.onTouchStart}
      onTouchMove={touch.onTouchMove}
    >
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

Conclusion

Si quelqu'un regarde vraiment le code attentivement, il peut y avoir A question. En plus d'utiliser les événements synthétiques de React, le contenu de touch.js n'a rien à voir avec React.

C’est bien le cas, cela n’a rien à voir avec réagir. L'explication est que ces données n'ont pas besoin d'être transmises via l'état de React ou l'état de Redux. Premièrement, en termes de performances, la mise à jour de l'état de Redux ou de React déclenchera le nouveau rendu de React, ce qui n'est pas nécessaire. peut être utilisé globalement. Je n’ai donc pas utilisé le mécanisme de réaction. En fait, c’est ce que React appelle les composants incontrôlés.

Enfin ci-joint le 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
};

Apprentissage recommandé : "tutoriel vidéo React"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn