React でのスライディングの実装方法

藏色散人
リリース: 2022-12-30 11:09:45
オリジナル
2212 人が閲覧しました

スライディングを実装するための React メソッド: 1. onTouchStart イベントでタッチを検索し、識別子に従って新しいタッチの発生を記録します; 2. 識別子に従ってタッチによって渡された各点の座標を記録しますonTouchMove イベント; 3. onTouchEnd イベントで、終了タッチ イベントを検索し、終了タッチ イベントが通過した点に基づいて実行されるジェスチャを計算します。

React でのスライディングの実装方法

このチュートリアルの動作環境: Windows 10 システム、react18.0.0 バージョン、Dell G3 コンピューター。

React でスライディングを実装するにはどうすればよいですか?

#反応して左右のスライド効果を実現する

反応してスライド ジェスチャを実装

React でのスライディングの実装方法
最近、モバイル端末のreactのスライドページめくり機能について少しやってみました。

検索を開始したところ、適切なライブラリが見つからないことがわかりました。唯一見つかったライブラリは、react-touch という名前のライブラリでした。一見したところ、フロントエンドには 4 ~ 500 個のスターが存在しましたworld === 自分でやりましたが、やりたいとは思えませんでした。必要な機能が必要な場合は、自分で書くことは忘れてください。

原理を確認すると、基本的には onTouchStart、onTouchMove、onTouchEnd の 3 つのイベントを使用してスライド ポイントを記録し、ジェスチャを計算します。

明らかにマルチタッチの場合は、各タッチ ポイントのパスを見つける必要があるため、次の手順があります:

  • onTouchStart イベントでタッチを見つけます。識別子に従って新しいものを記録します。 タッチが表示されます。

  • onTouchMove イベントでは、識別子に基づいてタッチによって通過した各点の座標を記録します。

  • onTouchEnd イベントで、終了タッチ イベントを見つけて、終了タッチ イベントが交差する点によって実行されるジェスチャを計算します。

私の場合、上下にスライドする機能だけが欲しいので、ワンタッチの状況だけに焦点を当てています。

次に、コードを書く準備をします。ああ、いいえ、まずそれをカプセル化する方法を考えなければなりません。自問自答を始めましょう:

シングルトン パターンを使用したいと考えています。

使用するのは面倒ですか?最初にインスタンス化する必要がありますか?

では、静的クラスを使用しますか?

すでに 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]()
    );
    // 向下翻页
  }
}
ログイン後にコピー

ここでは、2 ページ目のイベントの上下のみを判断しました、イベントに到達すると、イベントに登録されているすべてのコールバックが呼び出されます。複数のコールバックがある場合、必要に応じてコールバックの実行順序を調整できます。ここに秩序はないはずです。

インターフェース部分
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 を使用します。すべてのタッチ イベントをページ ディレクトリの _app.js ファイルにバインドします。

//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);
ログイン後にコピー

使い方を見てみましょう。
#
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>
  );
};
ログイン後にコピー

#ネイティブ React で使用します

#このプロジェクトは 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>
  );
}
ログイン後にコピー

結論

誰かがコードを注意深く読んだ場合、touch.js のコンテンツに問題がある可能性があります。 React の合成イベントには、React とは他に何も関係がないため、型破りに見えます。 これは確かに事実であり、react とは何の関係もありません。説明によると、これらのデータは、react の状態や redux の状態を介して渡す必要はありません。まず、パフォーマンスの観点から、redux または react の状態を更新すると、react の再レンダリングがトリガーされますが、これは必要ありません。第 2 に、これらのインターフェイスが機能することを期待しています。グローバルに使用できるため、react メカニズムは使用しませんでした。実際、これは React が制御されていないコンポーネントを呼び出すのと似ています。 最後に完全な 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 でのスライディングの実装方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート