組件在 ScrollView(Web)中的滾動(dòng)沖突與修復(fù))
移動(dòng)開發(fā)UI組件【免費(fèi)下載鏈接】react-native-gesture-handlerDeclarative API exposing platform native touch and gesture system to React Native.項(xiàng)目地址https://gitcode.com/gh_mirrors/re/react-native-gesture-handler點(diǎn)擊查看免費(fèi)下載本文檔基于 react-native-gesture-handler 倉(cāng)庫(kù)的packages/docs-gesture-handler/versioned_docs/version-2.x/guides/swipe-and-scroll.md編寫深入解析在 Web 平臺(tái)上自定義 swipeable 組件嵌入 ScrollView 后滾動(dòng)失效的根本原因以及通過GestureDetector的touchAction屬性pan-y進(jìn)行修復(fù)的方案。文章結(jié)合倉(cāng)庫(kù)源碼、官方文檔與測(cè)試用例幫助讀者理解touch-actionCSS 屬性與手勢(shì)識(shí)別之間的關(guān)系掌握在 ScrollView 中實(shí)現(xiàn)“既能左右滑動(dòng)又能上下滾動(dòng)”的完整實(shí)踐路徑。問題背景自定義 Swipeable 與 ScrollView 的滾動(dòng)沖突在 React Native Gesture Handler 中我們通常推薦直接使用官方提供的ReanimatedSwipeable組件來實(shí)現(xiàn)可滑動(dòng)的行或類似交互。該組件會(huì)在一個(gè)可平移的容器中渲染子內(nèi)容并支持左右滑動(dòng)滑動(dòng)過程中可根據(jù)用戶向左或向右滑動(dòng)的方向展示左右兩側(cè)的“操作容器”通過renderLeftActions或renderRightActions渲染。然而在某些場(chǎng)景下開發(fā)者需要自定義自己的 swipeable 組件以獲取對(duì)行為更多的控制權(quán)。例如需要定制滑動(dòng)閾值、自定義動(dòng)畫、或集成其他手勢(shì)邏輯。但自定義 swipeable 組件后一個(gè)常見的問題是當(dāng)該組件被放置在 ScrollView 內(nèi)部時(shí)滾動(dòng)不再工作。問題的本質(zhì)在于當(dāng)你的手勢(shì)處理器如 Pan在 Web 平臺(tái)上開始攔截觸摸事件后瀏覽器默認(rèn)的滾動(dòng)行為即 ScrollView 的滾動(dòng)會(huì)被禁用。這導(dǎo)致用戶滑動(dòng)時(shí)頁(yè)面無法上下滾動(dòng)。解決方案核心touchAction屬性修復(fù)該問題的關(guān)鍵是在GestureDetector上添加touchAction屬性并將其設(shè)置為pan-y如下所示GestureDetector gesture{...} ... touchActionpan-y ... /GestureDetector這樣做的原理是touch-action是 CSS 屬性它允許開發(fā)者指定在觸摸屏上如何允許用戶操作該元素例如平移、縮放。將其設(shè)置為pan-y意味著僅允許垂直方向的平移即上下滾動(dòng)而水平方向的平移如左右滑動(dòng)則交由你的手勢(shì)處理器來處理。這樣既保留了 ScrollView 的垂直滾動(dòng)能力又不影響自定義 swipeable 組件的水平滑動(dòng)功能。touchAction參數(shù)詳解在gesture-handlerCommon.ts中touchAction被定義為一個(gè)聯(lián)合類型支持所有 CSStouch-action取值export type TouchAction | auto | none | pan-x | pan-left | pan-right | pan-y | pan-up | pan-down | pinch-zoom | manipulation | inherit | initial | revert | revert-layer | unset;從源碼結(jié)構(gòu)看該類型覆蓋了 CSStouch-action規(guī)范中的全部取值。其中與滾動(dòng)沖突修復(fù)最相關(guān)的是取值含義none禁止所有瀏覽器默認(rèn)觸摸行為默認(rèn)值pan-y僅允許垂直方向平移保留上下滾動(dòng)pan-x僅允許水平方向平移auto瀏覽器自動(dòng)決定觸摸行為manipulation允許平移與縮放但禁用雙擊縮放GestureDetector的touchAction屬性在GestureDetector/index.tsx中被定義注釋明確指出該參數(shù)用于指定應(yīng)用于底層視圖的touchAction屬性支持所有 CSStouch-action值例如none、pan-y默認(rèn)值為none。這也是為何不設(shè)置touchAction時(shí)ScrollView 的滾動(dòng)會(huì)被禁用的直接原因手勢(shì)檢測(cè)器在 Web 上默認(rèn)將底層視圖的touch-action設(shè)置為none從而關(guān)閉了瀏覽器原生的滾動(dòng)行為。為什么默認(rèn)值是none源碼級(jí)原理在 Web 平臺(tái)上react-native-gesture-handler 通過GestureHandlerWebDelegate將手勢(shì)處理器的配置應(yīng)用到 DOM 元素上。其核心邏輯如下private setTouchAction() { const touchAction this.gestureHandler.touchAction; this.ensureView(this.view); const value this.gestureHandler.enabled ? (touchAction ?? DEFAULT_TOUCH_ACTION) : this.defaultViewStyles.touchAction; this.setViewStyle(touchAction, value); this.setViewStyle(WebkitTouchCallout, value); }而當(dāng)手勢(shì)處理器處于啟用狀態(tài)enabled且開發(fā)者未顯式指定touchAction時(shí)會(huì)使用常量DEFAULT_TOUCH_ACTION none。這意味著默認(rèn)情況下手勢(shì)處理器所綁定的 DOM 元素會(huì)被設(shè)置為touch-action: none瀏覽器將不再處理任何默認(rèn)觸摸行為——包括 ScrollView 的滾動(dòng)。這也解釋了為什么自定義 swipeable 組件嵌入 ScrollView 后滾動(dòng)失效Pan 手勢(shì)處理器啟用后其綁定的視圖的touch-action變?yōu)閚one水平方向的手勢(shì)swipeable 的滑動(dòng)被手勢(shì)庫(kù)接管但垂直方向的滾動(dòng)也被一并禁用了。而NativeViewGestureHandlerNativeViewGestureHandler.ts則會(huì)在合適的時(shí)機(jī)恢復(fù)視圖樣式例如view.style[touchAction] auto以還原默認(rèn)觸摸行為。修復(fù)方案的實(shí)施細(xì)節(jié)1. 在GestureDetector上設(shè)置touchActionpan-y這是文檔推薦的最小修復(fù)方案。直接在自定義 swipeable 組件內(nèi)部的GestureDetector上添加該屬性import { GestureDetector, Gesture } from react-native-gesture-handler; function CustomSwipeable({ children }) { const pan Gesture.Pan() .onUpdate((e) { // 處理水平滑動(dòng)邏輯 }); return ( GestureDetector gesture{pan} touchActionpan-y {children} /GestureDetector ); }這樣瀏覽器仍會(huì)保留垂直滾動(dòng)的默認(rèn)行為而水平滑動(dòng)則由 Pan 手勢(shì)處理。2. 使用官方ReanimatedSwipeable組件推薦如果你不需要完全自定義 swipeable 的行為建議直接使用官方組件import Swipeable from react-native-gesture-handler/ReanimatedSwipeable;在ReanimatedSwipeable.tsx中官方組件內(nèi)部已經(jīng)為 Pan 手勢(shì)和 Tap 手勢(shì)都設(shè)置了touchActionpan-yGestureDetector gesture{panGesture} touchActionpan-y Animated.View ... ... GestureDetector gesture{tapGesture} touchActionpan-y Animated.View style{[animatedStyle, childrenContainerStyle]} {children} /Animated.View /GestureDetector /Animated.View /GestureDetector因此使用官方ReanimatedSwipeable時(shí)無需手動(dòng)處理滾動(dòng)沖突——該組件在 Web 上已內(nèi)置了pan-y的touchAction配置。測(cè)試驗(yàn)證在倉(cāng)庫(kù)的 Web 手勢(shì)處理器單元測(cè)試GestureHandler.test.ts中對(duì)touchAction的配置傳遞與重置行為進(jìn)行了驗(yàn)證配置傳遞當(dāng)檢測(cè)器detector發(fā)送包含touchAction: pan-y的配置更新時(shí)handler.touchAction保持為pan-y默認(rèn)值恢復(fù)當(dāng)檢測(cè)器重新發(fā)送默認(rèn)值DEFAULT_TOUCH_ACTION即none時(shí)handler.touchAction恢復(fù)為none。這驗(yàn)證了touchAction屬性在 Web 平臺(tái)上會(huì)被完整傳遞到手勢(shì)處理器并在未設(shè)置時(shí)回退到默認(rèn)值none。其他相關(guān)屬性u(píng)serSelect與enableContextMenu除了touchAction之外GestureDetector在 Web 平臺(tái)上還提供另外兩個(gè)僅 Web 可用的屬性它們與touchAction共同組成“Web 視圖行為控制”三件套均定義于GestureDetector/index.tsx屬性類型默認(rèn)值說明touchActionTouchActionnone指定應(yīng)用于底層視圖的touch-actionCSS 屬性u(píng)serSelectnone \| auto \| textnone指定應(yīng)用于底層視圖的user-selectCSS 屬性enableContextMenubooleanfalse指定右鍵點(diǎn)擊底層視圖后是否啟用上下文菜單總結(jié)步驟操作說明1創(chuàng)建自定義 swipeable 組件使用Gesture.Pan()實(shí)現(xiàn)水平滑動(dòng)2將組件放入 ScrollView發(fā)現(xiàn)垂直滾動(dòng)失效3在GestureDetector上添加touchActionpan-y恢復(fù)垂直滾動(dòng)保留水平滑動(dòng)4可選使用官方ReanimatedSwipeable內(nèi)部已內(nèi)置pan-y配置核心要點(diǎn)默認(rèn)touch-action: none手勢(shì)處理器在 Web 上默認(rèn)將綁定視圖的touch-action設(shè)為none見constants.ts這會(huì)禁用 ScrollView 的原生滾動(dòng)pan-y的語(yǔ)義僅允許垂直平移水平滑動(dòng)交由手勢(shì)處理器處理從而實(shí)現(xiàn)“既能左右滑動(dòng)又能上下滾動(dòng)”官方組件已內(nèi)置ReanimatedSwipeable內(nèi)部對(duì) Pan 與 Tap 手勢(shì)均已設(shè)置touchActionpan-y無需手動(dòng)處理僅 Web 生效touchAction是 Web 平臺(tái)專屬屬性在 iOS / Android 原生平臺(tái)上由原生觸摸系統(tǒng)直接處理無需也不支持該配置。贊分享移動(dòng)開發(fā)UI組件【免費(fèi)下載鏈接】react-native-gesture-handlerDeclarative API exposing platform native touch and gesture system to React Native.項(xiàng)目地址https://gitcode.com/gh_mirrors/re/react-native-gesture-handler點(diǎn)擊查看免費(fèi)下載相關(guān)推薦react-native-gesture-handler Web 端自定義 Swipeable 組件在 ScrollView 中滾動(dòng)失效的修復(fù)touchActionpan-y 詳解react native gesture handler Web 端自定義 Swipeable 組件在 ScrollView 中滾動(dòng)失效的修復(fù)touchAct移動(dòng)開發(fā)UI組件LogicFlow中滑動(dòng)組件與自定義節(jié)點(diǎn)拖動(dòng)的沖突解決方案LogicFlow中滑動(dòng)組件與自定義節(jié)點(diǎn)拖動(dòng)的沖突解決方案 問題背景 在使用LogicFlow進(jìn)行流程圖編輯時(shí)開發(fā)者可能會(huì)遇到兩個(gè)常見的交互沖突問題 1.前端低代碼流程編排上一篇Windows熱鍵沖突終極解決方案Hotkey Detective熱鍵偵探完整指南下一篇如何用Calibre-Douban插件一鍵獲取豆瓣圖書元數(shù)據(jù)告別手動(dòng)整理的終極指南創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考