需求描述
系统中经常会有需要垂直滚动的页面,滚动容器的上下边一般都是“实”的,会将滚动内容清晰截断;如果在容器上下增加一段和背景同色的渐变遮罩层,那么滚动内容将产生一种“渐入渐出”的效果,对比如下:
实现要点
1、渐变遮罩层的z-index高于容器内容,需要给遮罩层加上pointer-events: none;让鼠标“穿透”到下层;
2、当内容滚动到顶部或底部时,需隐藏顶部或底部的遮罩层,防止遮挡显示内容;
3、外层容器带有圆角时,内层内容需要设置同样的圆角,否则滚动时圆角效果会出bug。
参考代码
此处附上本杂鱼封装的渐变遮罩层组件GradientCover代码,仅供参考:
<!-- 在可垂直滚动的div上下增加渐变色遮罩层,且滚动到顶部或底部时隐藏遮罩层 -->
<template>
<div id="GradientCover">
<div v-show="showGradientCover[0]" class="gradientMask top"
:style="`height: ${coverHeight}px;margin-bottom: -${coverHeight}px;`"
></div>
<div class="container" @scroll="scrollContent" ref="scrollContent"
:style="`overflow: ${overflow};border-radius: 0 0 ${borderRadius}px ${borderRadius}px;`"
>
<slot></slot>
</div>
<div v-show="showGradientCover[1]" class="gradientMask bottom"
:style="`height: ${coverHeight}px;margin-top: -${coverHeight}px;border-radius: 0 0 ${borderRadius}px ${borderRadius}px;`"
></div>
</div>
</template>
<script>
export default {
props: {
overflow: { // 是否可滚动
type: String,
default: () => 'hidden'
},
coverHeight: { // 遮罩高度
type: [String, Number],
default: () => 32
},
borderRadius: { // 外层容器圆角
type: [String, Number],
default: () => 0
}
},
data () {
return {
// 是否显示渐变遮罩层(初始处于顶部,不显示顶部遮罩,显示底部遮罩)
showGradientCover: [ false, this.overflow !== 'hidden' ]
}
},
watch: {
overflow: {
immediate: true,
handler (newVal) { // 页面滚动样式变化时,更新遮罩层可见配置
this.showGradientCover = [ false, newVal !== 'hidden' ]
}
}
},
methods: {
scrollContent (e) {
this.showGradientCover = [
// 滚动到距离顶部<20px时,隐藏顶部渐变遮罩层;否则显示
20 < e.srcElement.scrollTop,
// 滚动到距离底部<20px时,隐藏底部渐变遮罩层;否则显示
e.srcElement.scrollTop + e.srcElement.offsetHeight + 20
< e.srcElement.scrollHeight
]
},
scrollTop () { // 滚动到顶部
this.$refs.scrollContent.scrollTop= 0
}
}
}
</script>
<style lang="less" scoped>
#GradientCover {
height: 100%;
width: 100%;
.gradientMask {
pointer-events: none;
z-index: 100;
position: relative;
left: 0;
width: calc(100% - 8px); // 8px是滚动条的宽度
&.top {
top: 0;
background: linear-gradient(180deg, #ffffff, transparent);
}
&.bottom {
bottom: 0;
background: linear-gradient(0deg, #ffffff, transparent);
}
}
.container {
width: 100%;
height: 100%;
}
}
</style>