feat: 添加瀑布流滚动的安卓和ios的判断

This commit is contained in:
zerosaturation 2026-05-09 12:40:39 +08:00
parent b68ca3e7be
commit 5208bde803
2 changed files with 78 additions and 75 deletions

View File

@ -2,8 +2,8 @@
"name" : "TopFans", "name" : "TopFans",
"appid" : "__UNI__F199FF4", "appid" : "__UNI__F199FF4",
"description" : "", "description" : "",
"versionName" : "1.0.3", "versionName" : "1.0.4",
"versionCode" : 100, "versionCode" : 101,
"transformPx" : false, "transformPx" : false,
/* 5+App */ /* 5+App */
"app-plus" : { "app-plus" : {
@ -23,7 +23,8 @@
"modules" : { "modules" : {
"VideoPlayer" : {}, "VideoPlayer" : {},
"Camera" : {}, "Camera" : {},
"Speech" : {} "Speech" : {},
"Push" : {}
}, },
/* */ /* */
"distribute" : { "distribute" : {
@ -70,12 +71,7 @@
"secretkey" : "1i5Aj8FwL3i11LYPeXMRwRWycictWq2X" "secretkey" : "1i5Aj8FwL3i11LYPeXMRwRWycictWq2X"
} }
}, },
"push" : { "push" : {}
"unipush" : {
"version" : "2",
"offline" : false
}
}
}, },
"icons" : { "icons" : {
"android" : { "android" : {

View File

@ -78,8 +78,8 @@ const GAP = rpx2px(16)
const BORDER_W = rpx2px(2) const BORDER_W = rpx2px(2)
const SCALE = 0.9 const SCALE = 0.9
const ROWS = 4 const ROWS = 4
const AUTO_SCROLL_SPEED = 0.1 const AUTO_SCROLL_SPEED = 0.3
const AUTO_RESUME_DELAY = 1000 const AUTO_RESUME_DELAY = 1500
const PRELOAD_THRESHOLD = rpx2px(300) const PRELOAD_THRESHOLD = rpx2px(300)
// ========== ========== // ========== ==========
@ -112,62 +112,34 @@ let rafId = null
let userInteracting = false let userInteracting = false
let resumeTimer = null let resumeTimer = null
let appendTimer = null // let appendTimer = null //
let autoScrollPos = 0 //
let momentumTimer = null // iOS
let scrollUpdateTimer = null // scrollLeft
const startAutoScroll = () => { const startAutoScroll = () => {
if (!isComponentMounted) { if (!isComponentMounted) return
return
}
// RAF
if (rafId) { if (rafId) {
cafFn(rafId) cafFn(rafId)
rafId = null rafId = null
} }
//
userInteracting = false userInteracting = false
autoScrollPos = currentScrollLeft
let lastScrollLeft = 0 // // 使 scrollLeft
clearInterval(scrollUpdateTimer)
scrollUpdateTimer = setInterval(() => {
if (!isComponentMounted || userInteracting || isLoadingMore) return
autoScrollPos += AUTO_SCROLL_SPEED
scrollLeft.value = autoScrollPos
const step = () => { //
if (!isComponentMounted) { const remainingScroll = totalWidth.value - autoScrollPos - props.screenWidth
rafId = null
return
}
// RAF
if (!isComponentMounted) {
rafId = null
return
}
if (!userInteracting && !isLoadingMore) {
//
const actualScroll = scrollLeft.value
if (Math.abs(actualScroll - lastScrollLeft) > 5) {
//
currentScrollLeft = actualScroll
} else {
//
currentScrollLeft += AUTO_SCROLL_SPEED
scrollLeft.value = currentScrollLeft
lastScrollLeft = currentScrollLeft
}
//
const remainingScroll = totalWidth.value - currentScrollLeft - props.screenWidth
if (remainingScroll < Math.max(totalWidth.value / 2, props.screenWidth)) { if (remainingScroll < Math.max(totalWidth.value / 2, props.screenWidth)) {
// appendMore
// has_more
if (!isLoadingMore && !appendFailed && !isInitialLoading && props.useMockData) { if (!isLoadingMore && !appendFailed && !isInitialLoading && props.useMockData) {
appendMore() appendMore()
} }
} }
} else { }, 16)
//
lastScrollLeft = scrollLeft.value
currentScrollLeft = lastScrollLeft
}
rafId = rafFn(step)
}
rafId = rafFn(step)
} }
const stopAutoScroll = () => { const stopAutoScroll = () => {
@ -175,21 +147,41 @@ const stopAutoScroll = () => {
cafFn(rafId) cafFn(rafId)
rafId = null rafId = null
} }
clearInterval(scrollUpdateTimer)
scrollUpdateTimer = null
clearTimeout(appendTimer) clearTimeout(appendTimer)
appendTimer = null appendTimer = null
clearTimeout(resumeTimer) clearTimeout(resumeTimer)
resumeTimer = null resumeTimer = null
clearTimeout(momentumTimer)
momentumTimer = null
userInteracting = false userInteracting = false
isLoadingMore = false isLoadingMore = false
} }
const pauseForUser = () => { // iOS
userInteracting = true let lastTouchEndPos = 0 // touchend
clearTimeout(resumeTimer)
resumeTimer = setTimeout(() => { userInteracting = false }, AUTO_RESUME_DELAY) const detectMomentumEnd = () => {
clearTimeout(momentumTimer)
lastTouchEndPos = currentScrollLeft
const tick = () => {
momentumTimer = setTimeout(() => {
// lastTouchEndPostouchend
if (Math.abs(currentScrollLeft - lastTouchEndPos) < 3) {
autoScrollPos = currentScrollLeft
startAutoScroll()
} else {
//
lastTouchEndPos = currentScrollLeft
tick()
}
}, 60)
}
tick()
} }
// 500ms //
const scheduleAppend = () => { const scheduleAppend = () => {
if (!isComponentMounted || appendFailed) return if (!isComponentMounted || appendFailed) return
if (appendTimer) clearTimeout(appendTimer) if (appendTimer) clearTimeout(appendTimer)
@ -202,16 +194,23 @@ const scheduleAppend = () => {
} }
// ========== / ========== // ========== / ==========
const onTouchStart = () => pauseForUser() const onTouchStart = () => {
const onTouchEnd = () => {} userInteracting = true
clearTimeout(momentumTimer)
clearInterval(scrollUpdateTimer)
}
const onTouchEnd = () => {
// iOS
detectMomentumEnd()
}
const onScroll = (e) => { const onScroll = (e) => {
if (!isComponentMounted) return if (!isComponentMounted) return
currentScrollLeft = e.detail.scrollLeft currentScrollLeft = e.detail.scrollLeft
//
const remainingScroll = totalWidth.value - currentScrollLeft - props.screenWidth const remainingScroll = totalWidth.value - currentScrollLeft - props.screenWidth
if (remainingScroll < Math.max(totalWidth.value / 2, props.screenWidth)) { if (remainingScroll < Math.max(totalWidth.value / 2, props.screenWidth)) {
// has_more
if (!isLoadingMore && !appendFailed && !isInitialLoading && props.useMockData) { if (!isLoadingMore && !appendFailed && !isInitialLoading && props.useMockData) {
scheduleAppend() scheduleAppend()
} }
@ -681,12 +680,16 @@ onMounted(() => {
const handleVisibilityChange = () => { const handleVisibilityChange = () => {
if (!isComponentMounted) return if (!isComponentMounted) return
if (document.hidden) { if (document.hidden) {
userInteracting = true stopAutoScroll()
} else { } else {
userInteracting = false //
if (!rafId) { stopAutoScroll()
setTimeout(() => {
if (isComponentMounted) {
autoScrollPos = currentScrollLeft
startAutoScroll() startAutoScroll()
} }
}, 150)
} }
} }
@ -698,12 +701,15 @@ if (typeof document !== 'undefined') {
watch(() => props.isActive, (active) => { watch(() => props.isActive, (active) => {
if (!isComponentMounted) return if (!isComponentMounted) return
if (active) { if (active) {
userInteracting = false stopAutoScroll()
if (!rafId) { setTimeout(() => {
if (isComponentMounted) {
autoScrollPos = currentScrollLeft
startAutoScroll() startAutoScroll()
} }
}, 150)
} else { } else {
userInteracting = true stopAutoScroll()
} }
}, { immediate: false }) }, { immediate: false })
@ -712,6 +718,7 @@ onUnmounted(() => {
stopAutoScroll() stopAutoScroll()
clearTimeout(resumeTimer) clearTimeout(resumeTimer)
clearTimeout(appendTimer) clearTimeout(appendTimer)
clearTimeout(momentumTimer)
if (typeof document !== 'undefined') { if (typeof document !== 'undefined') {
document.removeEventListener('visibilitychange', handleVisibilityChange) document.removeEventListener('visibilitychange', handleVisibilityChange)
} }