如何让元素固定在手机键盘上?

问题描述 投票:0回答:1

我正在使用 editorJS 构建一个编辑器。对于 PC,我在视口滚动之后的顶部创建了一个粘性工具栏。然而,对于移动设备,由于该死的虚拟键盘,stickcy 工具栏不会固定在视口顶部。

所以我决定删除

position: sticky;
并为移动屏幕应用
position: fixed; bottom: 0;
,以便它粘在键盘顶部。我想我可以在
resize
scroll
事件处理程序中计算出工具栏的正确位置。手续如下。

  1. 如果
    resize
    发生,这意味着虚拟键盘向上/向下或浏览器页眉/页脚被滚动显示/消失。
  2. 去抖
    resize
    事件,以便在调整大小之前和
    visualViewport.height
    之后存储
    resize
  3. resize
    事件结束时,比较前后的
    visualViewport.height
    ,将差异设置为工具栏的
    style.bottom
  4. 如果
    scroll
    发生,
    visibility: hidden;
    工具栏并计算事件结束时的位置。 (也消除了
    scroll
    事件)
  5. 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)

javascript css mobile-safari android-softkeyboard uikeyboard
1个回答
0
投票

我找到了自己的解决方案。基本上每次调整大小、滚动事件发生时都会重新计算 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)
},
© www.soinside.com 2019 - 2024. All rights reserved.