我正在使用 editorJS 构建一个编辑器。对于 PC,我在视口滚动之后的顶部创建了一个粘性工具栏。然而,对于移动设备,由于该死的虚拟键盘,stickcy 工具栏不会固定在视口顶部。
所以我决定删除
position: sticky;
并为移动屏幕应用position: fixed; bottom: 0;
,以便它粘在键盘顶部。我想我可以在 resize
和 scroll
事件处理程序中计算出工具栏的正确位置。手续如下。
resize
发生,这意味着虚拟键盘向上/向下或浏览器页眉/页脚被滚动显示/消失。resize
事件,以便在调整大小之前和visualViewport.height
之后存储resize
。resize
事件结束时,比较前后的visualViewport.height
,将差异设置为工具栏的style.bottom
scroll
发生,visibility: hidden;
工具栏并计算事件结束时的位置。 (也消除了scroll
事件)visiblity: visible
工具栏以在键盘顶部显示它。但是,我无法实现它,因为 [2] 不起作用。即使有去抖,调整大小事件也没有在调整大小之前捕捉到
visualViewport.height
。
handleIOSKeyboardAppear(event) {
if (!this.isMobileResizing) {
console.log('start!', window.visualViewport?.height) <-- the same value
this.isMobileResizing = true
}
console.log('resizing...')
if (this.mobileResizeDebounceTimerId) {
clearTimeout(this.mobileResizeDebounceTimerId)
}
this.mobileResizeDebounceTimerId = setTimeout(() => {
console.log('end!', window.visualViewport?.height) <-- the same value
this.isMobileResizing = false
}, 500)
我找到了自己的解决方案。基本上每次调整大小、滚动事件发生时都会重新计算 style.bottom。
style.bottom 的值:
window.innerHeight - window.visualViewport.offsetTop - window.visualViewport.height
// MARK: hang events on creation.
created() {
if (this.isMobile) {
window.visualViewport?.addEventListener('resize', this.handleIOSKeyboardAppear)
window.addEventListener('scroll', this.handleMobileScroll)
}
}
...
handleMobileScroll(event) {
// MARK: hide the toolbar when scroll starts.
if (!this.isMobileScrolling) {
this.$refs.blockToolbar.style.visibility = 'hidden'
this.isMobileScrolling = true
}
if (this.mobileScrollDebounceTimerId !== null) {
clearTimeout(this.mobileScrollDebounceTimerId)
}
// MARK: if scroll ends, show the toolbar after 150ms.
this.mobileScrollDebounceTimerId = setTimeout(() => {
const toolbarBottomPosition =
window.innerHeight -
window.visualViewport?.offsetTop -
window.visualViewport?.height
const blockToolbar = this.$refs.blockToolbar
blockToolbar.style.visibility = 'visible'
blockToolbar.style.bottom = `${toolbarBottomPosition}px`
this.isMobileScrolling = false
}, 150)
},
handleIOSKeyboardAppear(event) {
// MARK: hide the toolbar when mobile VisualViewport resize starts.
if (!this.isMobileResizing) {
this.$refs.blockToolbar.style.visibility = 'hidden'
this.isMobileResizing = true
}
if (this.mobileResizeDebounceTimerId !== null) {
clearTimeout(this.mobileResizeDebounceTimerId)
}
// MARK: if mobile VisualViewport resize ends, show the toolbar.
this.mobileResizeDebounceTimerId = setTimeout(() => {
const toolbarBottomPosition =
window.innerHeight -
window.visualViewport?.offsetTop -
window.visualViewport?.height
this.$refs.blockToolbar.style.bottom = `${toolbarBottomPosition}px`
this.$refs.blockToolbar.style.visibility = 'visible'
this.isMobileResizing = false
}, 150)
},