fix(app): debounce viewport change handler, overflow hidden when keyboard open
50ms debounce prevents jittery resizing on mobile keyboard open/close. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
378b60820a
commit
9ba4854024
@@ -40,7 +40,7 @@ function onResize() { windowWidth.value = window.innerWidth }
|
||||
// actually shrinks when the keyboard opens (dvh doesn't do this reliably)
|
||||
const rootStyle = computed(() => {
|
||||
if (isMobile.value && isKeyboardOpen.value) {
|
||||
return { height: `${viewportHeight.value}px` }
|
||||
return { height: `${viewportHeight.value}px`, overflow: 'hidden' }
|
||||
}
|
||||
return {}
|
||||
})
|
||||
|
||||
@@ -17,13 +17,18 @@ export function useVisualViewport() {
|
||||
// Store the initial full height so we can compute keyboard offset
|
||||
let fullHeight = typeof window !== 'undefined' ? window.innerHeight : 0
|
||||
|
||||
function onViewportChange() {
|
||||
const vv = window.visualViewport
|
||||
if (!vv) return
|
||||
const kbHeight = Math.max(0, fullHeight - vv.height)
|
||||
keyboardHeight.value = kbHeight
|
||||
isKeyboardOpen.value = kbHeight > 100
|
||||
viewportHeight.value = vv.height
|
||||
let debounceTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
function onViewportChangeRaw() {
|
||||
if (debounceTimer) clearTimeout(debounceTimer)
|
||||
debounceTimer = setTimeout(() => {
|
||||
const vv = window.visualViewport
|
||||
if (!vv) return
|
||||
const kbHeight = Math.max(0, fullHeight - vv.height)
|
||||
keyboardHeight.value = kbHeight
|
||||
isKeyboardOpen.value = kbHeight > 100
|
||||
viewportHeight.value = vv.height
|
||||
}, 50)
|
||||
}
|
||||
|
||||
function onWindowResize() {
|
||||
@@ -40,8 +45,8 @@ export function useVisualViewport() {
|
||||
if (vv) {
|
||||
fullHeight = vv.height
|
||||
viewportHeight.value = vv.height
|
||||
vv.addEventListener('resize', onViewportChange)
|
||||
vv.addEventListener('scroll', onViewportChange)
|
||||
vv.addEventListener('resize', onViewportChangeRaw)
|
||||
vv.addEventListener('scroll', onViewportChangeRaw)
|
||||
}
|
||||
window.addEventListener('resize', onWindowResize)
|
||||
})
|
||||
@@ -49,8 +54,8 @@ export function useVisualViewport() {
|
||||
onUnmounted(() => {
|
||||
const vv = window.visualViewport
|
||||
if (vv) {
|
||||
vv.removeEventListener('resize', onViewportChange)
|
||||
vv.removeEventListener('scroll', onViewportChange)
|
||||
vv.removeEventListener('resize', onViewportChangeRaw)
|
||||
vv.removeEventListener('scroll', onViewportChangeRaw)
|
||||
}
|
||||
window.removeEventListener('resize', onWindowResize)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user