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