gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区

站長資訊網
最全最豐富的資訊網站

react怎么實現滑動

react實現滑動的方法:1、在onTouchStart事件找到touches,根據identifier中記錄新的touch出現;2、在onTouchMove事件中根據identifier來記錄每個touch經過的點的坐標;3、在onTouchEnd事件中,找到結束的touch事件,然后通過結束的touch事件劃過的點來計算要執行的手勢即可。

react怎么實現滑動

本教程操作環境:Windows10系統、react18.0.0版、Dell G3電腦。

react怎么實現滑動?

react 實現左右滑動效果

React 中滑動手勢的實現

react怎么實現滑動

最近做了一點關于react在移動端滑動翻頁的功能。

開始搜索了一下,發現居然沒找到合適的庫,唯一找到了名字叫react-touch的庫,一看,前端世界四五百star===自己擼,而且似乎也不是想要的功能,算了自己寫點吧。

看了下原理,基本就是配合onTouchStart,onTouchMove和onTouchEnd這三個事件,來記錄滑動過的點,然后來計算手勢。

顯然對于多點觸摸,需要找到每個點觸摸的路徑,所以有如下幾步:

  • 在onTouchStart事件找到touches,根據identifier中記錄新的touch出現。

  • 在onTouchMove事件中根據identifier來記錄每個touch經過的點的坐標。

  • 在onTouchEnd事件中,找到結束的touch事件,然后通過結束的touch事件劃過的點來計算要執行的手勢。

對于我來說我只是想要上下滑動的功能那么我就只關注單點觸摸的情況。

接下來準備上代碼。哦,不對,首先要想想要怎么封裝。開始自問自答:

我想用一個單例模式。

是不是使用有點太麻煩了,還要先實例化一下?

那用靜態類?

都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 (       <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 'react'; import logo from './logo.svg'; import './App.css'; 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的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視頻教程》

贊(0)
分享到: 更多 (0)
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
国产一线二线三线女| 视色,视色影院,视色影库,视色网| 红桃视频 国产| 丰满人妻中伦妇伦精品app| 国产精品久久久久9999爆乳| 精品日韩在线播放| 国内自拍中文字幕| 国产91在线亚洲| 成人网站免费观看入口| 97在线国产视频| 国产欧美日韩小视频| av无码久久久久久不卡网站| 成人一级生活片| heyzo国产| 无码人妻精品一区二区三区66| 日本成人中文字幕在线| 中文字幕网av| 日韩中文在线字幕| 欧美日本视频在线观看| 欧美视频第三页| 中文字幕第17页| 日韩欧美视频免费在线观看| av免费看网址| 99视频在线免费| 超碰成人在线免费观看| 97超碰在线视| 国产精品涩涩涩视频网站| 在线黄色免费观看| 成人免费a级片| 欧美精品成人网| 91免费网站视频| 国产亚洲欧美在线视频| 色片在线免费观看| 日本中文字幕在线视频观看| av免费在线播放网站| 最新中文字幕久久| 亚洲成人av免费看| 欧美中文字幕在线观看视频| 99精品视频播放| 国产av熟女一区二区三区| 黄色aaa级片| 青青视频免费在线| 另类小说第一页| 麻豆tv在线播放| 一级全黄肉体裸体全过程| 99久久久无码国产精品6| 亚洲精品天堂成人片av在线播放| 狠狠操精品视频| 你懂的av在线| 亚洲小说欧美另类激情| 免费涩涩18网站入口| youjizz.com在线观看| 91插插插影院| 九色91popny| 国产乱子夫妻xx黑人xyx真爽 | 高清一区二区视频| 日本免费一级视频| 91免费黄视频| 国产精品专区在线| 免费看日b视频| 欧美大片免费播放| 污免费在线观看| 不用播放器的免费av| 天堂一区在线观看| 欧美精品久久久久久久久25p| av免费看网址| 怡红院av亚洲一区二区三区h| 992tv快乐视频| 免费的av在线| 超碰成人免费在线| 欧美日韩成人免费视频| 9久久9毛片又大又硬又粗| 国产真实老熟女无套内射| 4444在线观看| 三上悠亚久久精品| 国产精品免费观看久久| 国产精品秘入口18禁麻豆免会员| 国产精品久久中文字幕| 国产91美女视频| 日本熟妇人妻中出| 人人爽人人爽av| 久久久成人精品一区二区三区 | 日韩av在线播放不卡| www插插插无码免费视频网站| 国产aaa免费视频| 成熟丰满熟妇高潮xxxxx视频| 国产91在线免费| 欧美成人福利在线观看| 911av视频| 又大又硬又爽免费视频| 精品国产成人av在线免| 欧美成人手机在线视频| 国产精品成人久久电影| 午夜欧美福利视频| 粉嫩av一区二区三区天美传媒| 精品久久久久久久久久中文字幕| 人妻熟女一二三区夜夜爱| 欧美性受xxxxxx黑人xyx性爽| 400部精品国偷自产在线观看| 国产精品无码av在线播放| 国产区二区三区| 国产欧美日韩小视频| 日本一二区免费| 成 年 人 黄 色 大 片大 全| 日本xxxx黄色| www国产黄色| 亚洲国产精品女人| 四季av一区二区| 久久久亚洲精品无码| 国产美女视频免费| 久久九九国产视频| 九色在线视频观看| 国产精品视频二| 女同激情久久av久久| 成人免费观看视频在线观看| 日韩最新中文字幕| 国产wwwxx| 精品视频一区二区在线| 免费人成自慰网站| 国产传媒久久久| 8x8x华人在线| 国产系列第一页| av噜噜在线观看| 亚洲欧美日韩三级| 不卡av免费在线| 久热免费在线观看| 37pao成人国产永久免费视频| 国产色一区二区三区| 一本大道东京热无码aⅴ| 中国一级黄色录像| 国产树林野战在线播放| 久久久国产精华液999999| 男人舔女人下面高潮视频| 精品久久一二三| 国内性生活视频| 成人午夜视频免费在线观看| 97在线播放视频| 成人免费xxxxx在线视频| 国产最新免费视频| 91av在线免费播放| 人妻无码视频一区二区三区| 欧美黄色免费影院| 我看黄色一级片| 午夜福利123| 黑人巨大国产9丨视频| 轻点好疼好大好爽视频| 国产va亚洲va在线va| 亚洲自偷自拍熟女另类| 99蜜桃臀久久久欧美精品网站| 欧美视频免费播放| 欧美激情第3页| 中国一级大黄大黄大色毛片| 波多野结衣av一区二区全免费观看| 无码人妻精品一区二区三区99v| 国产乱子伦精品无码专区| 91国视频在线| 日韩av.com| www.日本在线播放| 超碰在线人人爱| 久操手机在线视频| 一区二区三区 欧美| 看一级黄色录像| 久久久国产欧美| 精品少妇人妻av一区二区| 欧美亚洲日本一区二区三区| wwww.国产| 欧美国产视频一区| 高潮一区二区三区| 五十路熟女丰满大屁股| www.色欧美| 黄色国产一级视频| 国产美女视频免费看| 逼特逼视频在线| 99亚洲国产精品| 欧美午夜aaaaaa免费视频| 国产黄色片免费在线观看| 亚洲综合婷婷久久| 亚洲成熟丰满熟妇高潮xxxxx| 黑人巨大国产9丨视频| 欧美激情成人网| 你懂的av在线| 日韩精品第1页| 免费在线观看污网站| 91视频免费版污| 免费高清在线观看免费| 91成人综合网| 女同性恋一区二区| 久久6免费视频| 亚洲免费黄色网| 九九热在线免费| 黄色av免费在线播放| 欧美成人一区二区在线观看| avove在线观看| 中文字幕乱码免费| 一级全黄肉体裸体全过程| 一级黄色片在线免费观看| 亚洲美女爱爱视频| 九九热视频免费| 加勒比av中文字幕| 久久精品一二三四|