效果展示:吸顶

本部分非必读,旨在为有以下需求之一的开发者提供参考:

  • 需要判断页面滚动位置
  • 需要了解appear事件disappear事件

传统页面的实现思路

吸顶是传统 web 页面中的一种比较老的交互方式:

  • 吸顶元素的初始位置一般靠近页面顶部,但与顶部有一定的距离
  • 当手指向上滑动超过吸顶元素的初始位置时,把吸顶元素固定在顶部
  • 当手指向下滑动到达吸顶元素的初始位置时,取消吸顶元素在顶部的固定吸顶在传统 web 页面中的实现思路是监听scroll事件,当页面滚动到一定位置时,做一些事情来改变吸顶元素在窗口中的位置

框架的实现思路

然而,与传统 web 页面不同,在框架中,scroll事件仅适用于list组件,且获取的值是滚动的相对坐标值,在使用时,需要通过累加来获取当前滚动位置的绝对坐标

此外,scroll事件在列表滚动时会被高频触发,存在潜在性能问题

因此,在框架中,推荐开发者使用appear事件disappear事件来实现吸顶效果,appear事件在组件出现时触发,disappear事件在组件消失时触发

appear事件disappear事件是组件的通用事件,文档中标有支持通用事件的组件都支持这两个事件,包括div组件list-item组件

灵活使用appear事件disappear事件,能实现大部分需要判断滚动位置的需求

框架的具体实现与代码

接下来,对应在list组件中实现吸顶效果的示例代码,具体分析实现思路

首先,了解顶部元素吸顶元素

  • 列表中的顶部元素type属性toplist-item
  • 列表中的吸顶元素type属性ceilinglist-item然后,分析吸顶效果实现方案:

  • 使用stack组件做为整个页面的容器,stack组件的特性为:每个直接子组件按照先后顺序依次堆叠,覆盖前一个子组件

  • stack组件中增加一个排在最后的子组件,作为mask遮挡之前的子组件,显示效果为一直固定在顶部,这个mask吸顶元素渲染效果完全一致
  • 吸顶元素需要吸顶时,显示对应的mask,实现吸顶的效果;当吸顶元素不需要吸顶时,隐藏对应的mask最后,判断吸顶条件:

  • 当页面向下滚动到顶部元素消失在视野时,吸顶元素需要固定在顶部,因此,监听顶部元素disappear事件,显示mask

  • 当页面向上滚动到顶部元素出现在视野时,吸顶元素需要取消固定,因此,监听顶部元素appear事件,隐藏mask示例代码如下:
  1. <template>
  2. <!-- 利用stack组件,使"列表中的吸顶元素对应的Mask"覆盖列表 -->
  3. <stack class="tutorial-page">
  4. <list class="list">
  5. <!-- 通过监听"列表中的顶部元素"的元素的appear和disappear事件,控制"列表中的吸顶元素对应的Mask"的显示 -->
  6. <list-item type="top" ondisappear="showMask" onappear="hideMask">
  7. <div class="height-300 bg-blue">
  8. <text>列表中的顶部元素</text>
  9. </div>
  10. </list-item>
  11. <!-- 列表中的吸顶元素 -->
  12. <list-item type="ceiling">
  13. <div class="height-300 bg-red">
  14. <text>列表中的吸顶元素</text>
  15. </div>
  16. </list-item>
  17. <!-- 普通列表元素 -->
  18. <list-item for="list" type="common" class="list-item">
  19. <text class="text">{{$item}}</text>
  20. </list-item>
  21. </list>
  22. <!-- 列表中的吸顶元素对应的Mask -->
  23. <div show="{{maskShow}}">
  24. <div class="height-300 bg-red">
  25. <text>列表中的吸顶元素</text>
  26. </div>
  27. </div>
  28. </stack>
  29. </template>
  30. <style lang="less">
  31. .tutorial-page {
  32. flex-direction: column;
  33. .list {
  34. width: 750px;
  35. flex-grow: 1;
  36. .list-item {
  37. height: 150px;
  38. border-bottom-width: 1px;
  39. border-bottom-color: #0faeff;
  40. .text {
  41. flex: 1;
  42. text-align: center;
  43. }
  44. }
  45. }
  46. .height-300 {
  47. height: 300px;
  48. }
  49. .bg-red {
  50. flex-grow: 1;
  51. justify-content: center;
  52. background-color: #f76160;
  53. }
  54. .bg-blue {
  55. flex-grow: 1;
  56. justify-content: center;
  57. background-color: #0faeff;
  58. }
  59. }
  60. </style>
  61. <script>
  62. export default {
  63. private: {
  64. maskShow: false,
  65. appearCount: 0,
  66. list: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N']
  67. },
  68. onInit(){
  69. this.$page.setTitleBar({ text: '效果展示:吸顶' })
  70. },
  71. showMask () {
  72. this.maskShow = true
  73. },
  74. hideMask () {
  75. // 加载页面时,所有元素的appear事件都会被触发一次。因此,需要过滤第一次的appear事件
  76. if (this.appearCount) {
  77. this.maskShow = false
  78. } else {
  79. ++this.appearCount
  80. }
  81. }
  82. }
  83. </script>