欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何在React?Native開(kāi)發(fā)中防止滑動(dòng)過(guò)程中的誤觸

 更新時(shí)間:2023年05月06日 11:00:25   作者:suwu150  
在使用React?Native開(kāi)發(fā)的時(shí),當(dāng)我們快速滑動(dòng)應(yīng)用的時(shí)候,可能會(huì)出現(xiàn)誤觸,導(dǎo)致我們會(huì)點(diǎn)擊到頁(yè)面中的某一些點(diǎn)擊事件,誤觸導(dǎo)致頁(yè)面元素響應(yīng)從而進(jìn)行其他操作,表現(xiàn)出非常不好的用戶體驗(yàn)。

一、問(wèn)題背景

常見(jiàn)的情形是長(zhǎng)列表中,在滑動(dòng)過(guò)程中可能會(huì)出現(xiàn)誤觸到列表中的某一項(xiàng)的情形,對(duì)于用戶使用非常不好的體驗(yàn)。

如下列表組件中,就會(huì)存在滑動(dòng)過(guò)程中產(chǎn)生誤觸的情況。

import React from 'react';
import { 
  StyleSheet, Text, SafeAreaView,
  ScrollView,  View, TouchableOpacity, StatusBar,
} from 'react-native';
const App = () => {
  const list = Array.from(Array(100).keys());
  const onPress = (e) => {
    alert(1);
  };
  return (
    <SafeAreaView style={styles.container}>
      <ScrollView style={styles.scrollView}>
        {list.map((item) => {
          return (
            <TouchableOpacity onPress={onPress}>
              <View style={styles.containerView}>
                <Text style={styles.text}>{item}+ item</Text>
              </View>
            </TouchableOpacity>
          );
        })}
      </ScrollView>
    </SafeAreaView>
  );
};
const styles = StyleSheet.create({
  container: { flex: 1, paddingTop: StatusBar.currentHeight },
  scrollView: { marginHorizontal: 20 },
  text: { fontSize: 1 },
  containerView: { backgroundColor: 'pink', marginTop: 20, height: 50 },
});
export default App;

上面長(zhǎng)列表,在滾動(dòng)的過(guò)程中可能會(huì)出現(xiàn)誤觸的問(wèn)題。

二、解決思路

我們應(yīng)該如何處理這種情形,可以考慮從點(diǎn)擊事件上入手,考慮根據(jù)距離的移動(dòng)來(lái)進(jìn)行組織是否響應(yīng)點(diǎn)擊事件

通過(guò)查看官方文檔,我們能夠發(fā)現(xiàn)點(diǎn)擊時(shí)間在點(diǎn)擊按下和抬起的過(guò)程中有一個(gè)過(guò)程回調(diào),我們就可以利用這個(gè)回調(diào)進(jìn)行處理誤觸了,有興趣的小伙伴可以看看這塊官方說(shuō)明

由于點(diǎn)擊事件執(zhí)行過(guò)程原理

  • onPressIn 在按壓時(shí)被調(diào)用。
  • onPressOut 在按壓動(dòng)作結(jié)束后被調(diào)用。

在按下 onPressIn 后,將會(huì)出現(xiàn)如下兩種情況的一種:

用戶移開(kāi)手指,依次觸發(fā)onPressOut 和onPress事件。

按壓持續(xù) 500 毫秒以上,觸發(fā)onLongPress 事件。(onPressOut 在移開(kāi)手后依舊會(huì)觸發(fā)。)

可以通過(guò)監(jiān)聽(tīng)點(diǎn)擊事件的方式來(lái)監(jiān)聽(tīng)按鈕點(diǎn)擊,那我們來(lái)簡(jiǎn)單實(shí)現(xiàn)一個(gè)避免誤觸的方案

其中的核心原理就是點(diǎn)擊事件的整個(gè)過(guò)程,總結(jié)來(lái)說(shuō)就是下面的三個(gè)點(diǎn)擊過(guò)程

  onPressOut={(event) => {
    const [startX, startY] = [
      event.nativeEvent.pageX,
      event.nativeEvent.pageY,
    ];
    const currentTime = new Date().getTime();
    const shouldReject =
      (Math.abs(pressInPointRef.current.startX - startX) >
        pointDistance ||
        Math.abs(pressInPointRef.current.startY - startY) >
          pointDistance) &&
      (currentTime - pressInTime.current) < pointMinTimeSpace;
    console.log('shouldReject', shouldReject);
    shouldReject && event?.preventDefault?.();
  }}
  onPress={(event) => {
    if (event?.isDefaultPrevented?.()) return;
    onclick && onclick();
  }}
  onPressIn={(event) => {
    pressInPointRef.current.startX = event.nativeEvent.pageX;
    pressInPointRef.current.startY = event.nativeEvent.pageY;
    pressInTime.current = new Date().getTime();
  }}

當(dāng)發(fā)生觸摸時(shí),通過(guò)onPressIn事件記錄位置和獲取事件戳,當(dāng)指頭觸摸彈起時(shí),通過(guò)onPressOut事件記錄并且對(duì)比按下時(shí)的位置和按下時(shí)的時(shí)間,是否滿足響應(yīng)當(dāng)前點(diǎn)擊的條件,如果不滿足響應(yīng),則使用event?.preventDefault?.()阻止其繼續(xù)響應(yīng),最后根據(jù)onPress事件中if (event?.isDefaultPrevented?.()) return;判斷該如何響應(yīng)這次觸摸點(diǎn)擊,這就是整個(gè)過(guò)程。

pressInTime

調(diào)整按壓時(shí)間區(qū)間,在按下時(shí)和抬起間隔小于該時(shí)間,則認(rèn)為是誤觸,這個(gè)和距離區(qū)間(pointDistance)一起確定是否誤觸

pointDistance

調(diào)整按下和抬起時(shí)之間的距離,在按下時(shí)和抬起間隔小于該距離,則認(rèn)為是誤觸,這個(gè)和按壓時(shí)間(pressInTime)區(qū)間一起確定是否誤觸

調(diào)整顯示組件

其中TouchableOpacity組件可以更換為能夠響應(yīng)點(diǎn)擊事件的任何組件,下面是官方列出的被引用到的組件,都能夠使用這種方式處理誤觸。

 Button
 PanResponder
 Pressable
 ScrollView
 Text
 TextInput
 TouchableHighlight
 TouchableOpacity
 TouchableNativeFeedback
 TouchableWithoutFeedback
 View

針對(duì)以上情況,能夠?qū)⑵鋺?yīng)用到業(yè)務(wù)不同的誤觸情況下,下面是整理之后,完整的代碼,根據(jù)以上情況可以再次進(jìn)行組件封裝,適配自己業(yè)務(wù)組件的調(diào)整。

const App = () => {
  const list = Array.from(Array(100).keys());
  const pressInPointRef = useRef({ startX: 0, startY: 0 });
  const。pressInTime = useRef(0);
  const pointDistance = 100;
  const pointMinTimeSpace = 1000;
  const onclick = () => {
    console.log('按鈕被點(diǎn)擊...');
    alert('按鈕被點(diǎn)擊...')
  };
  return (
    <SafeAreaView style={styles.container}>
      <ScrollView style={styles.scrollView}>
        {list.map((item) => {
          return (
            <TouchableOpacity
              onPressOut={(event) => {
                const [startX, startY] = [
                  event.nativeEvent.pageX,
                  event.nativeEvent.pageY,
                ];
                const currentTime = new Date().getTime();
                const shouldReject =
                  (Math.abs(pressInPointRef.current.startX - startX) >
                    pointDistance ||
                    Math.abs(pressInPointRef.current.startY - startY) >
                      pointDistance) &&
                  (currentTime - pressInTime.current) < pointMinTimeSpace;
                console.log('shouldReject', shouldReject);
                shouldReject && event?.preventDefault?.();
              }}
              onPress={(event) => {
                if (event?.isDefaultPrevented?.()) return;
                onclick && onclick();
              }}
              onPressIn={(event) => {
                pressInPointRef.current.startX = event.nativeEvent.pageX;
                pressInPointRef.current.startY = event.nativeEvent.pageY;
                pressInTime.current = new Date().getTime();
              }}>
              <View style={styles.containerView}>
                <Text style={styles.text}>{item}+ line</Text>
              </View>
            </TouchableOpacity>
          );
        })}
      </ScrollView>
    </SafeAreaView>
  );
};

三、總結(jié)整理

  • 解決這次觸摸,主要是使用點(diǎn)擊事件本身的一個(gè)響應(yīng)機(jī)制,在中間通過(guò)記錄狀態(tài)值的方式去處理
  • 使用到的方法涉及到按下時(shí)、抬起時(shí)、按下這三個(gè)過(guò)程
  • 通用功能組件需要進(jìn)行封裝,以達(dá)到業(yè)務(wù)功能上的適配

到此這篇關(guān)于如何在React Native開(kāi)發(fā)中防止滑動(dòng)過(guò)程中的誤觸的文章就介紹到這了,更多相關(guān)React Native防止滑動(dòng)誤觸內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React中的ref屬性的使用示例詳解

    React中的ref屬性的使用示例詳解

    React 提供了 refrefref 屬性,讓我們可以引用組件的實(shí)例或者原生 DOM 元素,使用 refrefref,可以在父組件中調(diào)用子組件暴露出來(lái)的方法,或者調(diào)用原生 element 的 API,這篇文章主要介紹了React中的ref屬性的使用,需要的朋友可以參考下
    2023-04-04
  • React中ES5與ES6寫(xiě)法的區(qū)別總結(jié)

    React中ES5與ES6寫(xiě)法的區(qū)別總結(jié)

    這篇文章主要總結(jié)介紹了關(guān)于React中ES5與ES6的寫(xiě)法區(qū)別,文中介紹的非常詳細(xì),相信對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-04-04
  • react-routerV6版本和V5版本的詳細(xì)對(duì)比

    react-routerV6版本和V5版本的詳細(xì)對(duì)比

    React-Router5是React-Router6的前一個(gè)版本,它已經(jīng)被React-Router6取代,React-Router 6是一次較大的重大更新,本文就來(lái)介紹一下react-routerV6版本和V5版本的詳細(xì)對(duì)比,感興趣的可以了解一下
    2023-12-12
  • 一看就懂的ReactJs基礎(chǔ)入門教程-精華版

    一看就懂的ReactJs基礎(chǔ)入門教程-精華版

    現(xiàn)在最熱門的前端框架有AngularJS、React、Bootstrap等。自從接觸了ReactJS,ReactJs的虛擬DOM(Virtual DOM)和組件化的開(kāi)發(fā)深深的吸引了我,下面來(lái)跟我一起領(lǐng)略ReactJs的風(fēng)采吧~~ 文章有點(diǎn)長(zhǎng),耐心讀完,你會(huì)有很大收獲哦
    2021-04-04
  • 詳解React 條件渲染

    詳解React 條件渲染

    這篇文章主要介紹了React 條件渲染的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • React Hooks獲取數(shù)據(jù)實(shí)現(xiàn)方法介紹

    React Hooks獲取數(shù)據(jù)實(shí)現(xiàn)方法介紹

    這篇文章主要介紹了react hooks獲取數(shù)據(jù),文中給大家介紹了useState dispatch函數(shù)如何與其使用的Function Component進(jìn)行綁定,實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • React?18?如何更新?state?中的對(duì)象

    React?18?如何更新?state?中的對(duì)象

    state 中可以保存任意類型的JavaScript值,包括對(duì)象,但是,不應(yīng)該直接修改存放在 React state 中的對(duì)象,這篇文章主要介紹了React?18更新state中的對(duì)象,需要的朋友可以參考下
    2023-08-08
  • 基于Webpack4和React hooks搭建項(xiàng)目的方法

    基于Webpack4和React hooks搭建項(xiàng)目的方法

    這篇文章主要介紹了基于Webpack4和React hooks搭建項(xiàng)目的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • React.memo 和 useMemo 的使用問(wèn)題小結(jié)

    React.memo 和 useMemo 的使用問(wèn)題小結(jié)

    隨著代碼的增加,每次的狀態(tài)改變,頁(yè)面進(jìn)行一次 reRender ,這將產(chǎn)生很多不必要的 reRender 不僅浪費(fèi)性能,從而導(dǎo)致頁(yè)面卡頓,這篇文章主要介紹了React.memo 和 useMemo 的使用問(wèn)題小結(jié),需要的朋友可以參考下
    2022-11-11
  • React學(xué)習(xí)筆記之高階組件應(yīng)用

    React學(xué)習(xí)筆記之高階組件應(yīng)用

    這篇文章主要介紹了React 高階組件應(yīng)用,詳細(xì)的介紹了什么是React高階組件和具體使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06

最新評(píng)論