如果你想要一个听话的底部导航栏

2,031 阅读2分钟

先来看看不听话的

嗨.gif

这是为什么呢

看一看页面结构,大概是这个样子的

root
    container
        page
        footer

额么么,page是一个很多内容的div,可以把页面撑出滚动条。想让footer一直固定在底部的话用fixed,应该没什么问题!于是乎样式是这样的

 /*1*/
      .container {
        background-color: tan;
      }
      .page {
        background-color: teal;
        padding-bottom: 70px;
      }
      .page-item {
        padding: 150px 0;
      }
      .footer {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        height: 70px;
        background-color: tomato;
      }

再来看看听话的

嗨2.gif

页面结构与上面的一样。样式做了如下更改

     /*2*/
      .container 
        overflow: hidden;
        height: 100vh;
        width: 100%;
      }
      .page {
        width: 100%;
        height: 100%;
        box-sizing: border-box;
        overflow-y: scroll;
        padding-bottom: 70px;
      }

首先,将container的高度限制成视口高,并不允许滚动。其次让page允许滚动,并向上挤出导航栏的距离。

这样一来,滚动的就只是page不是container更不是浏览器窗口了。

遇到键盘弹起的情况

经过评论区的旁友提醒,试着考虑了一下这个情况。在原先代码不变的情况,键盘弹起时是这个样子的。

嗨no0k.gif

如果想键盘弹起的时候,底部导航栏不会被挤上来,要怎么做呢?

首先参考了一下这篇文章

然后将利用子绝父相规定page的位置

 .page {
        position: absolute;
        top: 20px;/*input框的高度*/
        bottom: 70px;/*底部导航栏的高度*/
        width: 100%;
        box-sizing: border-box;
        background-color: teal;
        overflow-y: scroll;
      }

根据参考文章,如果只是单纯地让导航栏消失,会留下一块背景色。这时候要让page的bottom变为0。

由于使用一个变量来控制导航栏的显示与否,这个变量也可以控制dom是否拥有某个样式,比如

<div class="page" :class="hideShow?'':'nobottom'">
<div class="footer" v-show="hideShow">看我动不动</div>

那么,最终的效果就是这样啦:

嗨0k.gif

完整代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>foooter</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
      body {
        padding: 0;
        margin: 0;
      }
      /*1*/
      /* .container {
        background-color: tan;
      }
      .page {
        background-color: teal;
        padding-bottom: 70px;
      }
      .page-item {
        padding: 150px 0;
      }
      .footer {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        height: 70px;
        background-color: tomato;
      } */
      /*2*/
      /*.container {
        background-color: tan;
        overflow: hidden;
        height: 100vh;
        width: 100%;
      }
      .page {
        width: 100%;
        height: 100%;
        box-sizing: border-box;
        background-color: teal;
        overflow-y: scroll;
        padding-bottom: 70px;
      }
      .page-item {
        padding: 150px 0;
      }
      .footer {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        height: 70px;
        background-color: tomato;
      }*/
      .container {
        background-color: tan;
        overflow: hidden;
        height: 100vh;
        width: 100%;
        position: relative;
      }
      .input {
        width: 200px;
        height: 20px;
        outline: none;
      }
      .page {
        position: absolute;
        top: 20px;
        bottom: 70px;
        width: 100%;
        box-sizing: border-box;
        background-color: teal;
        overflow-y: scroll;
      }
      .nobottom {
        bottom: 0;
      }
      .page-item {
        padding: 150px 0;
      }
      .footer {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        height: 70px;
        background-color: tomato;
      }
    </style>
  </head>
  <body>
    <div id="root">
      <div class="container">
        <input type="text" class="input" />
        <div class="page" :class="hideShow?'':'nobottom'">
          111
          <div class="page-item"></div>
          <div class="page-item"></div>
          <div class="page-item"></div>
          <div class="page-item"></div>
          <div class="page-item"></div>
          <div class="page-item"></div>
          <div class="page-item"></div>
          <div class="page-item"></div>
          <div class="page-item"></div>
          222
        </div>
        <div class="footer" v-show="hideShow">看我动不动</div>
      </div>
    </div>
      <script>
      const app = Vue.createApp({
        data() {
          return {
            hideShow: true,
            docmHeight: document.documentElement.clientHeight,
            showHeight: document.documentElement.clientHeight,
          };
        },
        mounted() {
          window.onresize = () => {
            return (() => {
              this.showHeight = document.body.clientHeight;
            })();
          };
        },
        watch: {
          showHeight() {
            if (this.docmHeight > this.showHeight) {
              this.hideShow = false;
            } else {
              this.hideShow = true;
            }
          },
        },
      });
      const vm = app.mount("#root");
    </script>
  </body>
</html>