START

  • 番茄大半夜不睡觉又来写点啥了。
  • 最近遇到苹果浏览器的展示bug,百度到有人说这是橡皮泥效果。
  • 简单的概括呢,就是一个html页面,本身是没有滚动条的,在安卓,pc上都是正常显示的,但是呢,苹果浏览器,就算你本身页面没有滚动条,还会出现一个滚动条,强行上拉拖拽就会样式乱码,影响到我们的滚动条事件。刚好最近写了一个顶部的导航栏,移动端一看,样式全部都乱套了。
  • 记录一下无滚动条页面,苹果手机默认携带的滚动条解决方案

问题说明

如下图

ios页面滚动条 iphone滚动条不能拖动_导航栏

demo代码

<template>
  <div id="app">

    <nav>
      滚动条距离顶部的距离{{lang}}
    </nav>

  </div>
</template>
<script>
export default {
  data() {
    return {
      lang: 0,
    };
  },
  methods: {
    scrollToTop() {
      // 1.获取滚动条距离顶部的距离
      let scrollTop =
        window.pageYOffset ||
        document.documentElement.scrollTop ||
        document.body.scrollTop;

      this.lang = scrollTop;
    },
  },
  mounted() {
    window.addEventListener("scroll", this.scrollToTop);
  },
  destroyed() {
    window.removeEventListener("scroll", this.scrollToTop);
  },
};
</script>

<style lang="scss">
</style>

解决方案

vue项目为例

1.导航栏使用 position: fixed;始终定为在顶部

2.导航栏的消失隐藏,绑定一个变量去控制样式,修改元素的opacity: 0;达到隐藏的效果

3.在滚动条事件中做特殊处理

js部分代码展示

export default {
  name: "Layout",
  components: {
    layoutFooter,
  },
  data() {
    return {
      // 控制移动端菜单是否展示的变量
      isMobileMenu: false,
      // 返回顶部按钮是否展示
      isTop: false,
      oldScrollTop: 0,

      // 滚动条距离顶部的举例
      scrollTop: 0,
      // 导航栏是否展示
      muneShow: true,
    };
  },
    /**
     *  滚动条滚动事件
     */
    scrollToTop() {
      // 1.获取滚动条距离顶部的距离
      let scrollTop =
        window.pageYOffset ||
        document.documentElement.scrollTop ||
        document.body.scrollTop;

      /**
       *  2.由于苹果存在橡皮糖的效果,就是一个本身没有滚动条的页面,强行上下拉扯也可以出现滚动条,
       *    所以如果 `滚动条距离顶部的距离 < 0` 正常浏览器就不可能会出现负的距离, 那么就是苹果浏览器了
       *    此方法可消除 无滚动条页面强行*从上往下滑动*对我们事件的影响
       * */
      if (scrollTop < 0) {
        return;
      }

      // 3.返回顶部按钮
      if (scrollTop > 300) {
        this.isTop = true;
      } else {
        this.isTop = false;
      }

      // 4.上滑
      if (this.scrollTop > scrollTop) {
        // 4.1 如果上次滚动条的距离 大于 当前滚动条距离  100px 说明用户向上滑动了网页,展示导航栏
        if (this.scrollTop - scrollTop > 100) {
          this.muneShow = true;
          this.scrollTop = scrollTop;
        }
      } else {
        // 5.下滑

        // 5.1 如果用户展开了移动端的菜单页面 不做滚动处理 这里优化了一下,防止因橡皮糖效果样式乱码。
        // 此方法可消除 无滚动条页面强行*下滑* 对我们事件的影响
        if (this.isMobileMenu) {
          return;
        }

        // 5.2 用户向下滑动页面, 隐藏导航栏 ; 记录当前滚动条距离顶部的长度
        this.muneShow = false;
        this.scrollTop = scrollTop;
      }

      // 5.3 处理一下为0的特殊情况
      if (scrollTop === 0) {
        this.scrollTop = 0;
        this.muneShow = true;
      }
    },
    
    // 返回顶部点击事件
    toTop() {
      document.body.scrollTop = 0;
      document.documentElement.scrollTop = 0;
      this.muneShow = false;
    },
   
  },
  mounted() {
    window.addEventListener("scroll", this.scrollToTop);
  },
  destroyed() {
    window.removeEventListener("scroll", this.scrollToTop);
  },
};

END

  • 当然也看到有其他的解决方案
  1. 类似于禁用全局的滚动条默认事件,不过这样的话并不友好,如果其他的地方使用到了滚动条,会直接导致不滚动
  2. 也看到有博客说可以针对需要滚动的地方,添加特殊处理,其他的地方,全部都禁用掉滚动条默认事件。有点繁琐,整半天还没我这个简单快捷…
  3. 由于当前需求没有涉及到底部导航栏,理论上原理和我这个顶部导航栏类似。
  4. 切记一点,导航栏使用position: fixed固定起来,这样就不会因为橡皮糖效果到处滑动,导致样式乱码。
  5. 其次,滚动条的事件中添加部分逻辑,可参考我上述贴出来的js代码,举一反三即可。
  • 这里也记录一下,禁用滚动条默认事件的方法。
document.body.addEventListener('touchmove', function (e) {
        e.preventDefault() // 阻止默认的处理方式(阻止下拉滑动的效果)
    }, {passive: false}) // passive 参数不能省略,用来兼容ios和android