START
- 番茄大半夜不睡觉又来写点啥了。
- 最近遇到苹果浏览器的展示bug,百度到有人说这是橡皮泥效果。
- 简单的概括呢,就是一个html页面,本身是没有滚动条的,在安卓,pc上都是正常显示的,但是呢,苹果浏览器,就算你本身页面没有滚动条,还会出现一个滚动条,强行上拉拖拽就会样式乱码,影响到我们的滚动条事件。刚好最近写了一个顶部的导航栏,移动端一看,样式全部都乱套了。
- 记录一下无滚动条页面,苹果手机默认携带的滚动条解决方案
问题说明
如下图
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
- 当然也看到有其他的解决方案
- 类似于禁用全局的滚动条默认事件,不过这样的话并不友好,如果其他的地方使用到了滚动条,会直接导致不滚动
- 也看到有博客说可以针对需要滚动的地方,添加特殊处理,其他的地方,全部都禁用掉滚动条默认事件。有点繁琐,整半天还没我这个简单快捷…
- 由于当前需求没有涉及到底部导航栏,理论上原理和我这个顶部导航栏类似。
- 切记一点,导航栏使用
position: fixed
固定起来,这样就不会因为橡皮糖效果到处滑动,导致样式乱码。 - 其次,滚动条的事件中添加部分逻辑,可参考我上述贴出来的js代码,举一反三即可。
- 这里也记录一下,禁用滚动条默认事件的方法。
document.body.addEventListener('touchmove', function (e) {
e.preventDefault() // 阻止默认的处理方式(阻止下拉滑动的效果)
}, {passive: false}) // passive 参数不能省略,用来兼容ios和android