移动端滚动状态隐藏滚动条

3,301 阅读4分钟

前言

最近在开发过程中有一个功能是类似于swiper那样的滑动条,下面有一个滑动的指示器来指示上面滑动到什么位置(但是这里实现方式不是用swiper实现的,使用swiper不会出现系统自带的滚动条)。

因此上面那部分系统自带的滑动滚动条业务就觉得不好看想去掉,于是开始找方法。

但是网上很多资料都是使用overflow:hidden,加了这个就由滑动变为裁减了,说了等于没说。

众所周知,移动端最难处理的就是兼容问题,因此找了很多方法都不能完全兼容。最后还是受到网上大佬们的启发自己写了一个才解决的。

使用css样式处理安卓端和部分ios

&::-webkit-scrollbar {
    width: 0;
    height: 0;
    display: none;
    -webkit-overflow-scrolling: touch;
    -overflow-scrolling: touch;
}

通过这种方法经过测试可以使安卓机的滚动条消失,iPhone13也可以,但是iphone7还是不行。不能适配所有的机型,所以我只能另想办法。

使用overflow将滚动条裁掉

也有很多的博客提到了这样的方法,但是没有给出具体的代码和示例,后来经过自己实践写了以下的一个小demo,经测试可以解决所有机型。

滚动条是当子元素的内容超出父元素的范围时,会在父元素的对应边界(例如纵向滑动滚动条就在纵向)出现滚动条。

一般情况下父子元素的宽高都是相同的,所以这个滚动条就会出现到父元素内侧。而这种方法的原理就是通过扩大父元素的边界来将滚动条移动到原有父元素的外侧,然后再将多出来的这部分使用overflow裁掉。

这里肯定有人要说不可能,你先是扩大了父元素的边界又妄想把扩大的这部分使用overflow裁掉这怎么可能?确实不可能,因此我们需要在父子元素中间嵌套一个div让他充当一个含有滚动条的假父元素被裁掉,而为最外层的真父元素设置overflow:hidden

以下demo是消除纵向滚动出现的滚动条,横向同理。

// react,其余和本示例无关的东西没贴出来,只贴了主要内容
<div className={style.out}>
    <div className={style.outContainer}>
        <div className={style.inContainer}>1111</div>
    </div>
</div>
// 样式名随便起的,莫吐槽

// 最外层真正的父元素设置overflow: hidden,将内层假父元素多出来的滚动条裁掉
.out {
    width: 250px;
    height:300px;
    overflow: hidden;
}
// 假父元素,通过padding-right的方式增加了一个滚动条的宽度用来放滚动条
.outContainer {
    width: 250px;
    height:300px;
    padding-right: 17px;
    border: solid 2px #000; //  仅仅为了看的清楚,与本示例无关可删掉
    overflow-y: scroll; // 使子元素支持纵向滚动
}
.inContainer {
    width: 250px;
    height:350px; // 子元素纵向超出50px
    background-color: aquamarine;
}

使用时注意的点

这个示例中的宽高都是定死的,但是在移动端操作中宽度大部分是100%定死的,高度往往却是由里面的内容撑开的。

上面的例子是隐藏的纵向滚动条需要在宽度方向加padding-right,而宽度100%是定死的,所以最外层父元素一定比中间的嵌套假父元素在宽度上小出一个滚动条。

但是如果是横向滑动隐藏横向滚动条,就需要在纵向加padding-bottom。由于纵向元素高度是逐级撑开的,当你在为中间嵌套的假父元素增加padding-bottom时,相应的真父元素高度也会被撑开,这样就无法裁剪。

因此这种方法的弊端就出现了,那就是在滚动的反方向父元素的对应尺寸一定是一个固定的值

例如横向滚动时,纵向的高度必须有一个固定大小的值来约束滚动条才能完成裁剪。纵向滚动时,横向的宽度必须有一个约定的值来约束滚动条才能完成裁剪。

当然我们也有办法解决,因为由内容撑开高度的大致有两种情况。

第一种是里面子元素是纯文字,当文字超出固定高度时滚动,那么这种情况一定会有一个固定高度。

第二种是里面的元素时一些需要循环的固定列表与表头标题的组合体。这种情况时我们可以通过使用表头标题尺寸和固定列表高度乘以利列表的数据长度来计算出一个固定的高度。通过行内样式的方式作用在最外层父元素,这样就能得到一个固定的高。