效果展示:吸顶
本部分非必读,旨在为有以下需求之一的开发者提供参考:
- 需要判断页面滚动位置
- 需要了解
appear事件
和disappear事件
传统页面的实现思路
吸顶
是传统 web 页面中的一种比较老的交互方式:
吸顶元素
的初始位置一般靠近页面顶部,但与顶部有一定的距离- 当手指向上滑动超过
吸顶元素
的初始位置时,把吸顶元素
固定在顶部 - 当手指向下滑动到达
吸顶元素
的初始位置时,取消吸顶元素
在顶部的固定吸顶
在传统 web 页面中的实现思路是监听scroll事件
,当页面滚动到一定位置时,做一些事情来改变吸顶元素
在窗口中的位置
框架的实现思路
然而,与传统 web 页面不同,在框架中,scroll事件
仅适用于list组件
,且获取的值是滚动的相对坐标值,在使用时,需要通过累加来获取当前滚动位置的绝对坐标
此外,scroll事件
在列表滚动时会被高频触发,存在潜在性能问题
因此,在框架中,推荐开发者使用appear事件
和disappear事件
来实现吸顶
效果,appear事件
在组件出现时触发,disappear事件
在组件消失时触发
appear事件
和disappear事件
是组件的通用事件,文档中标有支持通用事件的组件都支持这两个事件,包括div组件
、list-item组件
等
灵活使用appear事件
和disappear事件
,能实现大部分需要判断滚动位置的需求
框架的具体实现与代码
接下来,对应在list组件
中实现吸顶
效果的示例代码,具体分析实现思路
首先,了解顶部元素
和吸顶元素
:
- 列表中的
顶部元素
:type属性
为top
的list-item
列表中的
吸顶元素
:type属性
为ceiling
的list-item
然后,分析吸顶
效果实现方案:使用
stack组件
做为整个页面的容器,stack组件
的特性为:每个直接子组件按照先后顺序依次堆叠,覆盖前一个子组件- 在
stack组件
中增加一个排在最后的子组件,作为mask
遮挡之前的子组件,显示效果为一直固定在顶部,这个mask
与吸顶元素
渲染效果完全一致 当
吸顶元素
需要吸顶
时,显示对应的mask
,实现吸顶的效果;当吸顶元素
不需要吸顶
时,隐藏对应的mask
最后,判断吸顶
条件:当页面向下滚动到
顶部元素
消失在视野时,吸顶元素
需要固定在顶部,因此,监听顶部元素
的disappear事件
,显示mask
- 当页面向上滚动到
顶部元素
出现在视野时,吸顶元素
需要取消固定,因此,监听顶部元素
的appear事件
,隐藏mask
示例代码如下:
<template>
<!-- 利用stack组件,使"列表中的吸顶元素对应的Mask"覆盖列表 -->
<stack class="tutorial-page">
<list class="list">
<!-- 通过监听"列表中的顶部元素"的元素的appear和disappear事件,控制"列表中的吸顶元素对应的Mask"的显示 -->
<list-item type="top" ondisappear="showMask" onappear="hideMask">
<div class="height-300 bg-blue">
<text>列表中的顶部元素</text>
</div>
</list-item>
<!-- 列表中的吸顶元素 -->
<list-item type="ceiling">
<div class="height-300 bg-red">
<text>列表中的吸顶元素</text>
</div>
</list-item>
<!-- 普通列表元素 -->
<list-item for="list" type="common" class="list-item">
<text class="text">{{$item}}</text>
</list-item>
</list>
<!-- 列表中的吸顶元素对应的Mask -->
<div show="{{maskShow}}">
<div class="height-300 bg-red">
<text>列表中的吸顶元素</text>
</div>
</div>
</stack>
</template>
<style lang="less">
.tutorial-page {
flex-direction: column;
.list {
width: 750px;
flex-grow: 1;
.list-item {
height: 150px;
border-bottom-width: 1px;
border-bottom-color: #0faeff;
.text {
flex: 1;
text-align: center;
}
}
}
.height-300 {
height: 300px;
}
.bg-red {
flex-grow: 1;
justify-content: center;
background-color: #f76160;
}
.bg-blue {
flex-grow: 1;
justify-content: center;
background-color: #0faeff;
}
}
</style>
<script>
export default {
private: {
maskShow: false,
appearCount: 0,
list: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N']
},
onInit(){
this.$page.setTitleBar({ text: '效果展示:吸顶' })
},
showMask () {
this.maskShow = true
},
hideMask () {
// 加载页面时,所有元素的appear事件都会被触发一次。因此,需要过滤第一次的appear事件
if (this.appearCount) {
this.maskShow = false
} else {
++this.appearCount
}
}
}
</script>