diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 0a7e668..b766d69 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -38,7 +38,7 @@ -
+
@@ -167,23 +167,36 @@ function toggleUserMenu() { } // ── 左右滑动切换 tab ── -// 滑动顺序 = visibleTabs 的顺序(根据用户角色动态决定) -// 轮播区域(data-no-tab-swipe)内的滑动不触发 tab 切换 +// touch-action: pan-y on .main tells the browser to only handle vertical scroll natively, +// leaving horizontal swipe gestures to our JS handler. const swipeStartX = ref(0) const swipeStartY = ref(0) +const swipeEndX = ref(0) +const swipeEndY = ref(0) +const swipeStartTarget = ref(null) function onSwipeStart(e) { swipeStartX.value = e.touches[0].clientX swipeStartY.value = e.touches[0].clientY + swipeEndX.value = e.touches[0].clientX + swipeEndY.value = e.touches[0].clientY + swipeStartTarget.value = e.target } -function onSwipeEnd(e) { - const dx = e.changedTouches[0].clientX - swipeStartX.value - const dy = e.changedTouches[0].clientY - swipeStartY.value - // 必须是水平滑动 > 50px,且水平距离大于垂直距离 - if (Math.abs(dx) < 50 || Math.abs(dy) > Math.abs(dx)) return - // 轮播区域内不触发 tab 切换 - if (e.target.closest && e.target.closest('[data-no-tab-swipe]')) return +function onSwipeMove(e) { + swipeEndX.value = e.touches[0].clientX + swipeEndY.value = e.touches[0].clientY +} + +function onSwipeEnd() { + const dx = swipeEndX.value - swipeStartX.value + const dy = swipeEndY.value - swipeStartY.value + // Must be primarily horizontal (>60px) and more horizontal than vertical + if (Math.abs(dx) < 60 || Math.abs(dy) > Math.abs(dx)) return + // Carousel area excluded + if (swipeStartTarget.value?.closest?.('[data-no-tab-swipe]')) return + // Skip when modal/overlay is open + if (document.querySelector('.modal-overlay, .detail-overlay, .dialog-overlay')) return const tabs = visibleTabs.value.map(t => t.key) const currentIdx = tabs.indexOf(ui.currentSection) @@ -193,8 +206,7 @@ function onSwipeEnd(e) { if (dx < 0 && currentIdx < tabs.length - 1) nextIdx = currentIdx + 1 else if (dx > 0 && currentIdx > 0) nextIdx = currentIdx - 1 if (nextIdx >= 0) { - const tab = visibleTabs.value[nextIdx] - handleTabClick(tab) + handleTabClick(visibleTabs.value[nextIdx]) } }