refactor(HistoryDatabase): optimize card expansion behavior with debounce and animation lock

- Introduced a debounce mechanism to prevent rapid state changes during card expansion and collapse.
- Added an animation lock to avoid conflicts during transitions.
- Adjusted Intersection Observer thresholds and rootMargin for smoother detection and stability.
- Cleaned up resources on component unmounting to prevent memory leaks.
This commit is contained in:
666ghj
2026-01-09 10:46:32 +08:00
parent d90ec77f5d
commit dfab81a6c0

View File

@@ -104,6 +104,8 @@ const isExpanded = ref(false)
const hoveringCard = ref(null) const hoveringCard = ref(null)
const historyContainer = ref(null) const historyContainer = ref(null)
let observer = null let observer = null
let isAnimating = false // 动画锁,防止闪烁
let expandDebounceTimer = null // 防抖定时器
// 卡片布局配置 - 调整为更宽的比例 // 卡片布局配置 - 调整为更宽的比例
const CARDS_PER_ROW = 4 const CARDS_PER_ROW = 4
@@ -290,19 +292,48 @@ onMounted(() => {
loadHistory() loadHistory()
// 使用 Intersection Observer 监听滚动,自动展开/收起卡片 // 使用 Intersection Observer 监听滚动,自动展开/收起卡片
// 优化:使用防抖和动画锁防止闪烁
observer = new IntersectionObserver( observer = new IntersectionObserver(
(entries) => { (entries) => {
entries.forEach((entry) => { entries.forEach((entry) => {
if (entry.isIntersecting) { // 如果正在动画中,忽略新的触发
isExpanded.value = true if (isAnimating) return
} else {
isExpanded.value = false const shouldExpand = entry.isIntersecting
// 如果状态没有变化,不做任何处理
if (shouldExpand === isExpanded.value) return
// 清除之前的防抖定时器
if (expandDebounceTimer) {
clearTimeout(expandDebounceTimer)
expandDebounceTimer = null
} }
// 使用防抖延迟状态切换,防止快速闪烁
// 展开时延迟较短(50ms),收起时延迟较长(200ms)以增加稳定性
const delay = shouldExpand ? 50 : 200
expandDebounceTimer = setTimeout(() => {
// 再次检查是否正在动画
if (isAnimating) return
// 设置动画锁
isAnimating = true
isExpanded.value = shouldExpand
// 动画完成后解除锁定700ms 是动画时长)
setTimeout(() => {
isAnimating = false
}, 750)
}, delay)
}) })
}, },
{ {
threshold: [0.5], // 使用多个阈值,使检测更平滑
rootMargin: '0px 0px -150px 0px' threshold: [0.3, 0.5, 0.7],
// 调整 rootMargin使触发区域更稳定
rootMargin: '0px 0px -100px 0px'
} }
) )
@@ -315,10 +346,16 @@ onMounted(() => {
}) })
onUnmounted(() => { onUnmounted(() => {
// 清理 Intersection Observer
if (observer) { if (observer) {
observer.disconnect() observer.disconnect()
observer = null observer = null
} }
// 清理防抖定时器
if (expandDebounceTimer) {
clearTimeout(expandDebounceTimer)
expandDebounceTimer = null
}
}) })
</script> </script>