Rumah > hujung hadapan web > Soal Jawab bahagian hadapan > Bagaimana untuk melaksanakan gelongsor dalam tindak balas

Bagaimana untuk melaksanakan gelongsor dalam tindak balas

藏色散人
Lepaskan: 2022-12-30 11:09:45
asal
2238 orang telah melayarinya

Cara melaksanakan gelongsor dalam React: 1. Cari sentuhan dalam acara onTouchStart dan rekod kejadian sentuhan baharu mengikut pengecam 2. Rekod koordinat setiap titik yang dilalui oleh sentuhan mengikut pengecam masuk acara onTouchMove; 3. Dalam acara onTouchEnd, cari acara sentuhan penamat, dan kemudian hitung gerak isyarat yang akan dilakukan berdasarkan titik yang dipalang oleh acara sentuhan penamat.

Bagaimana untuk melaksanakan gelongsor dalam tindak balas

Persekitaran pengendalian tutorial ini: Sistem Windows 10, bertindak balas versi 18.0.0, komputer Dell G3.

Bagaimana untuk melaksanakan gelongsor dalam tindak balas?

Bertindak balas untuk melaksanakan kesan gelongsor kiri dan kanan

Pelaksanaan gerak isyarat gelongsor dalam React

Bagaimana untuk melaksanakan gelongsor dalam tindak balas

Baru-baru ini saya melakukan sedikit tentang fungsi memusing halaman gelongsor bagi bertindak balas pada terminal mudah alih.

Saya mula mencari dan mendapati saya tidak menemui perpustakaan yang sesuai. Satu-satunya perpustakaan yang saya temui ialah perpustakaan bernama react-touch Pada pandangan pertama, terdapat empat hingga lima ratus bintang di bahagian hadapan dunia === Saya tidak dapat mencarinya, dan saya seolah-olah tidak mahu Jika anda mahukan fungsi yang anda mahu, lupakan menulisnya sendiri.

Selepas melihat prinsip, ia pada asasnya berfungsi dengan tiga acara onTouchStart, onTouchMove dan onTouchEnd untuk merekodkan titik gelongsor dan kemudian mengira gerak isyarat.

Jelas sekali untuk pelbagai sentuhan, anda perlu mencari laluan setiap titik sentuh, jadi terdapat langkah berikut:

  • Cari sentuhan dalam acara onTouchStart dan rekod yang baharu mengikut pengecam Sentuhan muncul.

  • Dalam acara onTouchMove, rekodkan koordinat titik yang dilalui oleh setiap sentuhan berdasarkan pengecam.

  • Dalam acara onTouchEnd, cari acara sentuhan penamat, dan kemudian kira gerak isyarat yang akan dilakukan mengikut titik yang dipalang oleh acara sentuhan penamat.

Bagi saya, saya cuma mahukan fungsi gelongsor ke atas dan ke bawah, jadi saya hanya fokus pada situasi sentuhan tunggal.

Seterusnya, bersedia untuk menulis kod. Oh, tidak, mula-mula fikirkan cara membungkusnya. Mula tanya dan jawab sendiri:

Saya nak guna corak singleton.

Adakah ia terlalu menyusahkan untuk digunakan?

Kemudian gunakan kelas statik?

Jika anda sudah mempunyai js, apakah kelas statik yang diperlukan?

Baiklah, mari mulakan melancap.

Bahagian data

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

Bahagian sentuhan rekod

Acara di sini mengendalikan peristiwa sintetik reaksi, bukan peristiwa asli.

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

fungsi 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]()
    );
    // 向下翻页
  }
}
Salin selepas log masuk

Di sini saya hanya menilai Ada dua acara untuk halaman atas dan bawah Jika acara tercapai, semua panggilan balik yang didaftarkan untuk acara akan dipanggil. Jika terdapat berbilang panggilan balik, susunan pelaksanaan panggilan balik boleh dilaraskan mengikut keperluan. Tidak sepatutnya ada perintah di sini.

Bahagian antara muka

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

Tiada apa-apa untuk dikatakan, ia sangat ringkas dan kasar. Seterusnya, mari gunakannya sebagai tindak balas!

Gunakan

dalam next.js saya gunakan next.js+create-next-app. Ikat semua peristiwa sentuh dalam fail _app.js dalam direktori halaman.

//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);
Salin selepas log masuk

Mari lihat cara menggunakannya.

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>
  );
};
Salin selepas log masuk

Digunakan dalam native react

Projek ini dijana menggunakan 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>
  );
}
Salin selepas log masuk

Kesimpulan

Jika seseorang benar-benar membaca kod dengan teliti, mungkin terdapat masalah dengan sentuhan ini untuk menggunakan peristiwa sintetik react, kandungan dalam js tiada kaitan dengan react, yang nampaknya tidak konvensional.

Itu benar, ia tiada kaitan dengan reaksi. Penjelasan adalah bahawa data ini tidak perlu melalui keadaan reaksi atau keadaan redux Pertama, dari segi prestasi, pengemaskinian redux atau keadaan reaksi akan mencetuskan pemaparan semula, yang kedua, kami berharap bahawa antara muka ini boleh digunakan secara global Jadi saya tidak menggunakan mekanisme tindak balas. Malah, ini adalah seperti apa yang dipanggil tindak balas komponen tidak terkawal.

Akhirnya dilampirkan sentuhan lengkap.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
};
Salin selepas log masuk

Pembelajaran yang disyorkan: "tutorial video bertindak balas"

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan gelongsor dalam tindak balas. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan