1.问题

  • fixed布局的tab栏在安卓浏览器上,聚焦在输入框时,弹出的输入框会将tab栏顶到输入框上方,挡住页面。
  • fixed定位的tab栏
  • 出现的键盘将tab栏顶到页面中间

2.思路

  • 监听键盘弹出的事件…也就是监听页面的可见高度clientHeight
  • 先保存页面最初的可见高度,然后监听高度变化(resize),当新的高度小于原来的高度时,判断是键盘弹出
  • 键盘弹出时将tab栏隐藏起来
  • 实现效果

  • 代码如下,在全局(app.vue)添加
mounted() {
  window.addEventListener('resize', this.getShowHeight)
  },
beforeDestroy() {
    window.removeEventListener('resize', this.getShowHeight)
  },
methods: {
    getShowHeight() {
      this.showHeight = document.documentElement.clientHeight || document.body.clientHeight
      const diff = this.docmHeight - this.showHeight
      if (this.docmHeight > this.showHeight && diff > 120) {
        // 隐藏
        this.hideshow = false
      } else {
        // 显示
        this.hideshow = true
      }
    },
  }

3.优化

  • 上面已经实现了弹出键盘时不把tab栏顶上去,但是又有新问题…

3.1 问题1

  • 在ios微信的内置浏览器运行时,当路由栈不为空时,会显示一个前进/后退栏,这会使页面可见高度clientHeight小于初始大小,会触发上面隐藏按钮的条件,导致这样:
    第一次进入页面正常显示:


切换到其他页面(this.$router.push(…))之后再回到主页,底部出现了前进/后退栏,自定义的tab栏消失了:

3.2 思路

  • 进入页面的时候手动往路由栈中push一个空的路由,这样一进入页面就会显示底部的前进/后退栏,就可以获取到正确的页面可用高度:
mounted() {
    // 微信内置浏览器,默认添加一个空路由,调出前进/后退栏
    const isIOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
    if (isIOS) {
      window.history.pushState({}, 'title', '#')
    }
}
  • 效果:
    第一次进入页面:


切换到其他页面再返回:

  • 可以正常显示tab栏了~

3.3 问题2

  • 当页面列表较长时,往下滑到一定程度,前进/后退栏也会消失,在往上滑的时候会出现前进/后退栏,但是我们的tab栏却没有跟着上来。
  • 我这边的处理方法就是判断当前高度与初始高度的差值,如果是键盘的话,差值在400以上,如果是微信的前进/后退栏大概是100左右,我用120来判断:
  • 当差值大于120就判断为是键盘弹出,否则就不隐藏tab栏。改进getShowHeight方法
getShowHeight() {
      this.showHeight = document.documentElement.clientHeight || document.body.clientHeight
      const diff = this.docmHeight - this.showHeight
      if (this.docmHeight > this.showHeight && diff > 120) {
        // 隐藏
        this.hideshow = false
      } else {
        // 显示
        this.hideshow = true
      }
    },

完整代码

<template>
  <div id="app" ref="app" :class="isNeedNav?'isNeedNav':''">
    <router-view />
<!-- tab组件 -->
    <g-nav :nav-list="navList" v-show="isNeedNav && hideshow" />
  </div>
</template>

<script>
import GNav from '@/components/GNav'
export default {
  components: {
    GNav
  },
  data() {
    return {
      isNeedNav: false,
      navList: [],
      docmHeight: document.documentElement.clientHeight || document.body.clientHeight,
      showHeight: document.documentElement.clientHeight || document.body.clientHeight,
      hideshow: true // 显示或者隐藏footer
    }
  },
  mounted() {
    // 微信内置浏览器,默认添加一个空路由,调出前进/后退栏
    const isIOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
    if (isIOS) {
      window.history.pushState({}, 'title', '#')
    }
    this.getShowHeight()
    window.addEventListener('resize', this.getShowHeight)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.getShowHeight)
  },
  methods: {
    getShowHeight() {
      this.showHeight = document.documentElement.clientHeight || document.body.clientHeight
      const diff = this.docmHeight - this.showHeight
      if (this.docmHeight > this.showHeight && diff > 120) {
        // 隐藏
        this.hideshow = false
      } else {
        // 显示
        this.hideshow = true
      }
    }
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐