Heim > Web-Frontend > Front-End-Fragen und Antworten > So implementieren Sie das Einschieben von Reaktionen

So implementieren Sie das Einschieben von Reaktionen

藏色散人
Freigeben: 2022-12-30 11:09:45
Original
2240 Leute haben es durchsucht

So implementieren Sie das Gleiten in React: 1. Suchen Sie Berührungen im Ereignis onTouchStart und zeichnen Sie das Auftreten neuer Berührungen gemäß der Kennung auf. 2. Zeichnen Sie die Koordinaten jedes von der Berührung passierten Punkts gemäß der Kennung im Ereignis onTouchMove auf. 3. Suchen Sie im onTouchEnd-Ereignis das Endberührungsereignis und berechnen Sie dann die auszuführende Geste basierend auf dem Punkt, den das Endberührungsereignis kreuzt.

So implementieren Sie das Einschieben von Reaktionen

Die Betriebsumgebung dieses Tutorials: Windows 10-System, Reaktionsversion 18.0.0, Dell G3-Computer.

Wie implementiert man eine Sliding-In-Reaktion?

react realisiert den linken und rechten Schiebeeffekt.

Ich habe mit der Suche begonnen und festgestellt, dass ich keine geeignete Bibliothek finden konnte. Auf den ersten Blick stellte ich fest, dass es in der Front-End-Welt vier- bis fünfhundert Sterne gab === ich selbst, und es schien nicht die Funktion zu sein, die ich wollte. Vergiss es, schreibe einfach selbst welche. Nachdem wir uns das Prinzip angeschaut haben, funktioniert es grundsätzlich mit den drei Ereignissen onTouchStart, onTouchMove und onTouchEnd, um den Gleitpunkt zu erfassen und dann die Geste zu berechnen.
Natürlich müssen Sie für Multi-Touch den Pfad jedes Berührungspunkts finden, daher gibt es die folgenden Schritte:

So implementieren Sie das Einschieben von ReaktionenFinden Sie die Berührungen im onTouchStart-Ereignis und zeichnen Sie das neue Berührungsereignis entsprechend der Kennung auf.

Zeichnen Sie im onTouchMove-Ereignis die Koordinaten jedes durch die Berührung passierten Punkts basierend auf der Kennung auf.

Suchen Sie im onTouchEnd-Ereignis das Endberührungsereignis und berechnen Sie dann die Geste, die von dem Punkt ausgeführt werden soll, der vom Endberührungsereignis gekreuzt wird.

  • Für mich möchte ich nur die Funktion des Auf- und Abgleitens, also konzentriere ich mich nur auf die Single-Touch-Situation.

  • Als nächstes bereiten Sie sich darauf vor, den Code zu schreiben. Oh nein, zuerst müssen wir darüber nachdenken, wie wir es einkapseln. Fangen Sie an, sich selbst zu fragen und zu antworten:
  • Ich möchte ein Singleton-Muster verwenden.

  • Ist die Verwendung zu mühsam? Muss ich es zuerst instanziieren?
  • Dann statische Klassen verwenden?

  • Wenn Sie bereits über js verfügen, welche weiteren statischen Klassen werden benötigt? Geben Sie einfach ein Wörterbuch aus und fertig.

Okay, dann fangen wir an zu masturbieren.

Datenteil

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

Touch-Teil aufzeichnen

Die Ereignisse hier behandeln synthetische Reaktionsereignisse, keine nativen Ereignisse.
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函数来处理手势判断逻辑并执行回调
Nach dem Login kopieren

HandleTouch-Funktion
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]()
    );
    // 向下翻页
  }
}
Nach dem Login kopieren

Hier beurteile ich nur zwei Ereignisse, Seite auf und ab, wenn das Ereignis erreicht ist, werden alle für das Ereignis registrierten Rückrufe aufgerufen. Bei mehreren Rückrufen kann die Ausführungsreihenfolge der Rückrufe nach Bedarf angepasst werden. Hier sollte es keine Ordnung geben.

Schnittstellenteil
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
};
//输出所有接口函数
Nach dem Login kopieren

Da gibt es nicht viel zu sagen, es ist einfach so einfach und grob. Als nächstes verwenden wir es in React!

Mit in next.js verwende ich next.js+create-next-app. Binden Sie alle Berührungsereignisse in der Datei _app.js im Seitenverzeichnis.

//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);
Nach dem Login kopieren

Mal sehen, wie man es als nächstes verwendet.

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>
  );
};
Nach dem Login kopieren
Wird in nativer Reaktion verwendet

Dieses Projekt wird mit der Create-React-App generiert

//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>
  );
}
Nach dem Login kopieren

FazitWenn sich jemand den Code wirklich genau ansieht, kann es sein A Frage: Abgesehen von der Verwendung synthetischer Ereignisse in touch.js scheint es unkonventionell zu sein.

Das ist tatsächlich so, es hat nichts mit der Reaktion zu tun. Die Erklärung ist, dass diese Daten nicht über den React- oder Redux-Status geleitet werden müssen. Erstens löst die Aktualisierung des Redux- oder React-Status ein erneutes Rendern aus, was zweitens nicht erforderlich ist kann global verwendet werden. Daher habe ich den Reaktionsmechanismus nicht verwendet. Tatsächlich ist dies so etwas wie das, was React als unkontrollierte Komponenten bezeichnet.

Schließlich im Anhang ist das komplette 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
};
Nach dem Login kopieren
Empfohlenes Lernen: „React-Video-Tutorial

Das obige ist der detaillierte Inhalt vonSo implementieren Sie das Einschieben von Reaktionen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage