Compare commits
1 Commits
fix/export
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| bac5e0a26a |
@@ -38,7 +38,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Main content -->
|
||||
<div class="main" @touchstart="onSwipeStart" @touchend="onSwipeEnd">
|
||||
<div class="main" @touchstart.passive="onSwipeStart" @touchmove.passive="onSwipeMove" @touchend="onSwipeEnd" style="touch-action: pan-y">
|
||||
<router-view />
|
||||
</div>
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user