久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長(zhǎng)資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

react怎么實(shí)現(xiàn)滑動(dòng)

react實(shí)現(xiàn)滑動(dòng)的方法:1、在onTouchStart事件找到touches,根據(jù)identifier中記錄新的touch出現(xiàn);2、在onTouchMove事件中根據(jù)identifier來(lái)記錄每個(gè)touch經(jīng)過(guò)的點(diǎn)的坐標(biāo);3、在onTouchEnd事件中,找到結(jié)束的touch事件,然后通過(guò)結(jié)束的touch事件劃過(guò)的點(diǎn)來(lái)計(jì)算要執(zhí)行的手勢(shì)即可。

react怎么實(shí)現(xiàn)滑動(dòng)

本教程操作環(huán)境:Windows10系統(tǒng)、react18.0.0版、Dell G3電腦。

react怎么實(shí)現(xiàn)滑動(dòng)?

react 實(shí)現(xiàn)左右滑動(dòng)效果

React 中滑動(dòng)手勢(shì)的實(shí)現(xiàn)

react怎么實(shí)現(xiàn)滑動(dòng)

最近做了一點(diǎn)關(guān)于react在移動(dòng)端滑動(dòng)翻頁(yè)的功能。

開(kāi)始搜索了一下,發(fā)現(xiàn)居然沒(méi)找到合適的庫(kù),唯一找到了名字叫react-touch的庫(kù),一看,前端世界四五百star===自己擼,而且似乎也不是想要的功能,算了自己寫(xiě)點(diǎn)吧。

看了下原理,基本就是配合onTouchStart,onTouchMove和onTouchEnd這三個(gè)事件,來(lái)記錄滑動(dòng)過(guò)的點(diǎn),然后來(lái)計(jì)算手勢(shì)。

顯然對(duì)于多點(diǎn)觸摸,需要找到每個(gè)點(diǎn)觸摸的路徑,所以有如下幾步:

  • 在onTouchStart事件找到touches,根據(jù)identifier中記錄新的touch出現(xiàn)。

  • 在onTouchMove事件中根據(jù)identifier來(lái)記錄每個(gè)touch經(jīng)過(guò)的點(diǎn)的坐標(biāo)。

  • 在onTouchEnd事件中,找到結(jié)束的touch事件,然后通過(guò)結(jié)束的touch事件劃過(guò)的點(diǎn)來(lái)計(jì)算要執(zhí)行的手勢(shì)。

對(duì)于我來(lái)說(shuō)我只是想要上下滑動(dòng)的功能那么我就只關(guān)注單點(diǎn)觸摸的情況。

接下來(lái)準(zhǔn)備上代碼。哦,不對(duì),首先要想想要怎么封裝。開(kāi)始自問(wèn)自答:

我想用一個(gè)單例模式。

是不是使用有點(diǎn)太麻煩了,還要先實(shí)例化一下?

那用靜態(tài)類(lèi)?

都js了還要啥靜態(tài)類(lèi),輸出個(gè)字典完事。

那好吧,開(kāi)始擼吧。

數(shù)據(jù)部分

const touchData = { touching: false, trace: [] }; // 單點(diǎn)觸摸,所以只要當(dāng)前在觸摸中,就可以把劃過(guò)的點(diǎn)記錄到trace中了 function* idGenerator() {   let start = 0;   while (true) {     yield start;     start += 1;   } } //這個(gè)生成器用來(lái)生成不同事件回調(diào)的id,這樣我們可以注冊(cè)不同的回調(diào),然后在不需要的時(shí)候刪掉。 const callbacks = {   onSlideUpPage: { generator: idGenerator(), callbacks: {} },   onSlideDownPage: { generator: idGenerator(), callbacks: {} } }; //存儲(chǔ)向上、下?lián)Q頁(yè)的回調(diào)函數(shù)
登錄后復(fù)制

記錄觸摸部分

這里的事件處理的是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事件,如果是多點(diǎn)觸摸直接清空所有數(shù)據(jù)。如果是單點(diǎn)觸摸,記錄第一個(gè)點(diǎn),并設(shè)置狀態(tài) function onTouchMove(evt) {   if (!touchData.touching) return;   touchData.trace.push({     x: evt.touches[0].screenX,     y: evt.touches[0].screenY   }); } //如果在單點(diǎn)觸摸過(guò)程中,持續(xù)記錄觸摸的位置。 function onTouchEnd() {   if (!touchData.touching) return;   let trace = touchData.trace;   touchData.touching = false;   touchData.trace = [];   handleTouch(trace);  //判斷touch類(lèi)型并調(diào)用適當(dāng)回調(diào) } //在觸摸結(jié)束事件,中調(diào)用handleTouch函數(shù)來(lái)處理手勢(shì)判斷邏輯并執(zhí)行回調(diào)
登錄后復(fù)制

handleTouch函數(shù)

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]()     );      // 向上翻頁(yè)   } else if (start.y - end.y > 200) {     Object.keys(callbacks.onSlideDownPage.callbacks).map(key =>       callbacks.onSlideDownPage.callbacks[key]()     );     // 向下翻頁(yè)   } }
登錄后復(fù)制

在這里我只判斷了向上向下翻頁(yè)兩個(gè)事件,如果事件達(dá)成,則會(huì)調(diào)用所有注冊(cè)到該事件的回調(diào)。如果有多個(gè)回調(diào)可按照需求對(duì)回調(diào)的執(zhí)行順序進(jìn)行調(diào)整。這里應(yīng)該是無(wú)序的。

接口部分

function addSlideUpPage(f) {   let key = callbacks.onSlideUpPage.generator.next().value;   callbacks.onSlideUpPage.callbacks[key] = f;   return key; } //注冊(cè)向上滑動(dòng)回調(diào)并返回回調(diào)id function addSlideDownPage(f) {   let key = callbacks.onSlideDownPage.generator.next().value;   callbacks.onSlideDownPage.callbacks[key] = f;   return key; } //注冊(cè)向下滑動(dòng)回調(diào)并返回回調(diào)id function removeSlideUpPage(key) {   delete callbacks.onSlideUpPage.callbacks[key]; } //使用回調(diào)id刪除向上滑動(dòng)回調(diào) function removeSlideDownPage(key) {   delete callbacks.onSlideDownPage.callbacks[key]; } //使用回調(diào)id刪除向下滑動(dòng)回調(diào) export default {   onTouchEnd,   onTouchMove,   onTouchStart,   addSlideDownPage,   addSlideUpPage,   removeSlideDownPage,   removeSlideUpPage }; //輸出所有接口函數(shù)
登錄后復(fù)制

這沒(méi)啥說(shuō)的,就是折麼簡(jiǎn)單粗暴。接下來(lái),就在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>  { // 將所有導(dǎo)出的touch事件綁定在最外層的div上 // 這樣就可以全局注冊(cè)事件了 }         </Provider>       </Container>     );   } }  export default withReduxStore(MyApp);
登錄后復(fù)制

接下來(lái)看看如何使用。

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>   ); };
登錄后復(fù)制

在原生react中使用

這個(gè)項(xiàng)目使用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>   ); }
登錄后復(fù)制

結(jié)語(yǔ)

如果真的有人仔細(xì)看了代碼,可能會(huì)有個(gè)問(wèn)題,這個(gè)touch.js里的內(nèi)容除了使用了react的合成事件,然后就沒(méi)react什么事了,好像不太常規(guī)。

的確是這樣,就沒(méi)關(guān)react什么事了。解釋就是這些數(shù)據(jù)不用通過(guò)react的state或者redux的state太傳遞,一來(lái)是在性能上,一更新redux或者react的state就會(huì)觸發(fā)react的重新渲染,沒(méi)有必要,二就是希望可以全局使用這些接口,所以就并沒(méi)有借助react的機(jī)制。其實(shí)這就像是react所說(shuō)的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 };
登錄后復(fù)制

推薦學(xué)習(xí):《react視頻教程》

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
国产精品视频一区视频二区| 国产一区91| 久久精品二区三区| 美女毛片一区二区三区四区最新中文字幕亚洲 | 国产色噜噜噜91在线精品| 亚州av乱码久久精品蜜桃| а√天堂8资源中文在线| 国产激情久久| 久久亚洲精品中文字幕蜜潮电影| 久久av资源| 久久国产欧美日韩精品| 日本亚洲最大的色成网站www| 鲁大师成人一区二区三区| 少妇久久久久| 国产无遮挡裸体免费久久| 日韩中文字幕一区二区高清99| 9色精品在线| 欧美日韩精品一本二本三本| 欧美午夜精品一区二区三区电影| 欧美日韩免费看片| 亚久久调教视频| 亚洲在线一区| 国产精品日韩欧美一区| 伊人久久高清| 欧美香蕉视频| 国产一区二区三区久久| 欧美亚洲日本精品| 精品欧美日韩精品| 久久精品国产网站| 国产精品香蕉| 精品视频久久| 成人黄色av| 日韩精品一区二区三区av| 亚洲精品乱码| 亚洲日本久久| 欧美精品国产白浆久久久久| 国产精品欧美在线观看| 中文字幕av一区二区三区四区| 在线国产一区| 免费在线观看视频一区| 日韩精品免费视频一区二区三区 | 国产一区调教| 日韩中文欧美| 欧美日韩四区| 香蕉久久一区| 乱一区二区av| 国产精品极品在线观看| 久久久国产精品网站| 九九久久国产| 亚洲成a人片| 三级精品视频| 麻豆9191精品国产| 日本不卡视频一二三区| 国产毛片久久久| 成人一区而且| 九九综合九九| 日韩一区中文| 粉嫩av一区二区三区四区五区 | 美日韩精品视频| 久久国产人妖系列| 在线成人动漫av| 国产欧美一区| 在线一区电影| 成人一区而且| 日韩欧美精品一区二区综合视频| 日本久久黄色| 日韩高清一区二区| 久久九九精品| 国产精品成人国产| 热久久久久久久| 岛国av在线网站| 日韩精品视频中文字幕| 日韩免费视频| 国产欧美精品| 国产亚洲在线观看| 麻豆视频在线看| 欧美在线看片| 久热re这里精品视频在线6| 色爱综合网欧美| 日韩精品免费一区二区夜夜嗨| 久久精品国产大片免费观看| 精品少妇一区| 91精品国产自产观看在线 | 国产亚洲一区二区手机在线观看 | 伊人久久av| 国产精品美女午夜爽爽| 老鸭窝毛片一区二区三区| 日韩国产综合| 麻豆国产欧美一区二区三区| 蜜桃av一区二区在线观看| se01亚洲视频 | 欧美日韩四区| 日韩天堂在线| 国产成人免费| 免费看久久久| 国产精品亲子伦av一区二区三区 | 亚洲国产一区二区三区在线播放 | 久久久成人网| 亚洲精品**中文毛片| 美女性感视频久久| 欧美日本不卡高清| 日本不卡一二三区黄网| 久久亚洲二区| 在线一区免费观看| 国产精品99一区二区| 91精品韩国| 精品一区二区三区四区五区| 国产伦精品一区二区三区千人斩 | 精品视频自拍| 免费日韩一区二区三区| 国产日韩在线观看视频| 日韩国产在线观看| 日韩精品亚洲专区| 日韩美女精品| 日本不卡视频一二三区| 99热精品久久| 久色成人在线| 国产精品二区不卡| 国产精品一区三区在线观看| 日本v片在线高清不卡在线观看| 蜜桃久久av| 99视频精品| 三级在线观看一区二区| 亚洲男女自偷自拍| 久久亚洲不卡| 日欧美一区二区| 日韩国产欧美三级| 欧美偷窥清纯综合图区| 青青草视频一区| 国产极品久久久久久久久波多结野 | 福利一区二区免费视频| 欧美激情亚洲| 久久久久久久欧美精品| 国产日产精品_国产精品毛片 | 精品一区二区三区免费看| 精品视频一区二区三区四区五区| 美女视频网站久久| 麻豆国产91在线播放| 麻豆精品在线| 久久香蕉精品香蕉| 天堂中文av在线资源库| 欧美aa在线观看| 波多野结衣一区| 日韩亚洲国产欧美| 视频一区中文字幕精品| 国产精品一区毛片| 国产在线看片免费视频在线观看| 成人午夜国产| 亚洲一区二区三区高清| 日本综合视频| 精品久久99| 欧美日韩中文一区二区| 蜜臀久久久久久久| 国产欧美精品久久| 国产成人免费精品| 一区二区三区视频免费观看| 国产精品外国| 国产探花在线精品| 国产伦理久久久久久妇女| 国产va在线视频| 亚洲一区二区毛片| 久久国产三级| 水蜜桃精品av一区二区| 午夜精品网站| 91欧美极品| 肉色欧美久久久久久久免费看| 中文在线一区| 国产精品嫩模av在线| 婷婷成人综合| 日本一区免费网站| 国产91在线精品| 亚洲综合精品四区| 国产精品主播| 久久久久国产精品一区三寸| 蜜桃久久精品一区二区| 国产乱人伦丫前精品视频| 亚洲区国产区| 欧美另类中文字幕| 日韩电影免费网站| 亚洲香蕉视频| 丰满少妇一区| 日韩中文字幕一区二区三区| 美女在线视频一区| 欧美特黄一区| 精品久久免费| 亚洲丝袜美腿一区| 中文在线а√天堂| 日韩中文欧美在线| 国产调教一区二区三区| 亚洲夜间福利| 国产精品网址| 午夜欧美视频| 精品99久久| 亚洲精品九九| 99精品在线| 精品国产午夜| 日韩欧美在线精品| 激情综合网站| 欧美xxxx中国| 国产私拍福利精品视频二区|