scroll.md 18.2 KB
Newer Older
M
init  
miaodian 已提交
1 2 3 4
## Scroll

滚动列表,提供了优质的原生滚动体验,便捷的配置项和事件,是一个基于`better-scroll`进行封装的组件。

D
dolymood 已提交
5 6 7 8 9 10
### 滚动原理

  由于 better-scroll 的滚动原理为:在滚动方向上,第一个子元素的长度超过了容器的长度。

  那么对于 Scroll 组件,其实就是内容元素`.cube-scroll-content`在滚动方向上的长度必须大于容器元素 `.cube-scroll-wrapper`。根据滚动方向的不同,有以下两种情况:

T
tank0317 已提交
11
  1)纵向滚动:**内容元素的高度必须大于容器元素**。由于容器元素的高度默认会被子元素的高度撑开,所以为了满足我们的滚动前提,你需要给 Scroll 组件的 `.cube-scroll-wrapper`元素一个非弹性高度。
D
dolymood 已提交
12

T
tank0317 已提交
13
  2)横向滚动:**内容元素的宽度必须大于容器元素**。由于在默认情况下,子元素的宽度不会超过容器元素,所以需要给 Scroll 组件的 `.cube-scroll-content` 元素设置大于 `.cube-scroll-wrapper` 的宽度。
D
dolymood 已提交
14

F
fengweiyao 已提交
15 16
  > 注意:任何时候如果出现无法滚动的情况,都应该首先查看内容元素`.cube-scroll-content`的元素高度/宽度是否大于容器元素`.cube-scroll-wrapper`的高度/宽度。这是内容能够滚动的前提条件。**如果内容存在图片的情况,可能会出现 DOM 元素渲染时图片还未下载,因此内容元素的高度小于预期,出现滚动不正常的情况。此时你应该在图片加载完成后,比如 onload 事件回调中,手动调用 Scroll 组件的 `refresh()` 方法,它会重新计算滚动距离。**

M
init  
miaodian 已提交
17 18
### 示例

T
tank0317 已提交
19
5 个示例代码快速了解如何使用 Scroll 组件。
M
init  
miaodian 已提交
20

F
fengweiyao 已提交
21
- **1. 基本使用 - Default**
T
tank0317 已提交
22 23

  通过设置 `data` 属性为一个数组,即可生成能够在容器内优雅滚动的列表。完整示例代码在[这里](https://github.com/didi/cube-ui/blob/master/example/pages/scroll/default.vue)
M
init  
miaodian 已提交
24 25

  ```html
T
tank0317 已提交
26 27 28 29 30 31 32
  <div class="scroll-list-wrap">
    <cube-scroll
      ref="scroll"
      :data="items"
      :options="options">
    </cube-scroll>
  </div>
M
init  
miaodian 已提交
33 34
  ```

A
AmyFoxFN 已提交
35
  ```stylus
T
tank0317 已提交
36 37
  .scroll-list-wrap
    height: 350px
A
AmyFoxFN 已提交
38 39
  ```

T
tank0317 已提交
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
  > **注意**:由上面的滚动原理可知,这里给滚动容器提供一个固定高度是必须的,同时只有在滚动内容的高度大于容器高度时才可滚动。

`options`中可以设置滚动条是否可见以及初始滚动位置`startY/startX`

  Scroll 组件提供了一个`scrollTo()`方法,可以手动控制列表滚动位置。

  ```javascript
  scrollTo() {
    this.$refs.scroll.scrollTo(
      0,
      this.scrollToY,
      this.scrollToTime,
      ease[this.scrollToEasing]
    )
  },
  ```
A
AmyFoxFN 已提交
56

T
tank0317 已提交
57
  实际上这是一个非常有用的方法,如当我们想要实现“点击不同锚点,列表滚动到相应位置展现不同内容”时,可以使用`scrollTo()`方法。
A
AmyFoxFN 已提交
58

F
fengweiyao 已提交
59
- **2. 横向滚动 - Horizontal**
M
init  
miaodian 已提交
60

F
fengweiyao 已提交
61
  Scroll 组件支持横向滚动,只需指定`direction="horizontal"`,同时需要添加相应样式如下。完整示例代码在[这里](https://github.com/didi/cube-ui/blob/master/example/pages/scroll/horizontal.vue)
M
init  
miaodian 已提交
62 63

  ```html
F
fengweiyao 已提交
64 65 66 67 68 69 70 71 72
  <cube-scroll
    ref="scroll"
    :data="items"
    direction="horizontal"
    class="horizontal-scroll-list-wrap">
    <ul class="list-wrapper">
      <li v-for="item in items" class="list-item">{{ item }}</li>
    </ul>
  </cube-scroll>
M
init  
miaodian 已提交
73
  ```
T
tank0317 已提交
74 75

  ```stylus
F
fengweiyao 已提交
76 77 78 79 80
  .horizontal-scroll-list-wrap
    border: 1px solid rgba(0, 0, 0, 0.1)
    border-radius: 5px
    .cube-scroll-content
      display: inline-block
T
tank0317 已提交
81 82 83 84
    .list-wrapper
      padding: 0 10px
      line-height: 60px
      white-space: nowrap
F
fengweiyao 已提交
85 86
    .list-item
      display: inline-block
M
init  
miaodian 已提交
87 88
  ```

F
fengweiyao 已提交
89 90 91
  > **注意**:1. 由上面的滚动原理可知,这里的 CSS 样式设置是必须的,只有在滚动内容的宽度大于容器宽度时才可滚动。2. 有时候我们希望横向滚动使用`Scroll`组件来模拟,纵向保留浏览器原生滚动,或者相反的情况。这时你需要传递 better-scroll 配置项 [eventPassthrough](http://ustbhuangyi.github.io/better-scroll/doc/zh-hans/options.html#eventpassthrough)。

  这里对样式的设定做简要的解释,为`list-item`元素添加`display: inline-block`是希望元素能够不换行,单行显示。`list-wrapper`添加`white-space: nowrap`是希望遇到父元素边界,依然不换行。另外,关键是`cube-scroll-content`元素添加`display: inline-block`样式,此时`cube-scroll-content`元素的宽度为能够包裹子孙元素的最小宽度,即为连续内联`list-item`元素的宽度之和子元素的最大宽度。具有同样性质的样式还有,浮动元素和绝对定位元素,在不设置具体宽度时,其宽度为包裹子孙元素的最小宽度。
T
tank0317 已提交
92

F
fengweiyao 已提交
93
- **3. 自定义内容和上拉刷新下拉加载 - Customized**
M
init  
miaodian 已提交
94

T
tank0317 已提交
95
  `Scroll`组件支持通过插槽自定义列表内容和样式。完整示例代码在[这里](https://github.com/didi/cube-ui/blob/master/example/pages/scroll/config.vue)
M
init  
miaodian 已提交
96 97

  ```html
T
tank0317 已提交
98 99 100
  <div class="scroll-list-wrap">
    <cube-scroll
      ref="scroll"
F
fengweiyao 已提交
101
      :data="items"
T
tank0317 已提交
102 103 104 105 106 107
      :options="options"
      @pulling-down="onPullingDown"
      @pulling-up="onPullingUp">
      ... // 自定义内容
    </cube-scroll>
  </div>
M
init  
miaodian 已提交
108
  ```
T
tank0317 已提交
109

F
fengweiyao 已提交
110
  Scroll 组件还支持下拉刷新和上拉加载的能力。默认无下拉刷新/上拉加载,可通过`options`传递配置项`pullDownRefresh``pullUpLoad`开启相应功能。开启后,下拉时,Scroll 组件会展示默认下拉动画以及派发`pulling-down`事件,你可以监听`pulling-down`事件更新数据。同理,开启上拉加载后,可通过`pulling-up`事件更新数据。
T
tank0317 已提交
111

F
fengweiyao 已提交
112
  `pullDownRefresh`的相关配置有:下拉阈值(threshold), 回弹位置(stop), 更新成功文案(txt)和文案显示时间(stopTime)。`pullDownRefresh``pullUpLoad`对象的所有配置项和含义见 [Props 配置](#/zh-CN/docs/scroll#cube-Props配置-anchor)
T
tank0317 已提交
113

M
init  
miaodian 已提交
114
  ```javascript
T
tank0317 已提交
115 116 117
  ... // 省略非核心代码
  computed: {
    options() {
M
init  
miaodian 已提交
118
      return {
T
tank0317 已提交
119 120 121
        pullDownRefresh: this.pullDownRefreshObj,
        pullUpLoad: this.pullUpLoadObj,
        scrollbar: true
M
init  
miaodian 已提交
122 123
      }
    },
T
tank0317 已提交
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
    ...
  },
  methods: {
    onPullingDown() {
      // 模拟更新数据
      setTimeout(() => {
        if (Math.random() > 0.5) {
          // 如果有新数据
          this.items.unshift(_foods[1])
        } else {
          // 如果没有新数据
          this.$refs.scroll.forceUpdate()
        }
      }, 1000)
    },
    onPullingUp() {
      // 模拟更新数据
      setTimeout(() => {
        if (Math.random() > 0.5) {
          // 如果有新数据
          let newPage = _foods.slice(0, 5)
          this.items = this.items.concat(newPage)
        } else {
          // 如果没有新数据
          this.$refs.scroll.forceUpdate()
        }
      }, 1000)
    },
    ...
M
init  
miaodian 已提交
153 154 155
  }
  ```

F
fengweiyao 已提交
156
  > **注意**:如果请求结果没有数据更新,则必须调用 Scroll 组件的`forceUpdate()`方法结束此次下拉刷新/上拉加载,这样 Scroll 组件才会开始监听下一次下拉刷新/上拉加载操作。在上例中数据更新时,没有调用`forceUpdate()`方法,原因为:**如果你向`Scroll`组件传递了`data`属性,那么当`Scroll`组件监听到`data`有更新时会自行调用`forceUpate(true)`方法**,因此推荐传递`data`属性。
A
AmyFoxFN 已提交
157

F
fengweiyao 已提交
158
- **4. 自定义下拉刷新动画 - 仿京东 App 首页**
M
init  
miaodian 已提交
159

F
fengweiyao 已提交
160
  如果你不喜欢内置的下拉刷新和上拉加载动画,还可以用[作用域插槽](https://cn.vuejs.org/v2/guide/components.html#作用域插槽)做自定义动画。Scroll 组件的作用域插槽暴露出的变量非常完善,可以满足绝大多数场景下自定义下拉/上拉动画的需求。下面的例子模仿了京东 App 首页的下拉刷新动画。完整示例代码在[这里](https://github.com/didi/cube-ui/blob/master/example/pages/scroll/jd.vue)
M
init  
miaodian 已提交
161 162 163 164

  ```html
  <cube-scroll
    ref="scroll"
T
tank0317 已提交
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
    :scroll-events="['scroll']"
    :options="scrollOptions"
    @scroll="onScrollHandle"
    @pulling-down="onPullingDown">
    <img src="http://om0jxp12h.bkt.clouddn.com/jd_content.JPG">
    <template slot="pulldown" slot-scope="props">
      <div v-if="props.pullDownRefresh"
        class="cube-pulldown-wrapper"
        :style="pullDownStyle">
        <div class="pulldown-content">
          <img src="http://om0jxp12h.bkt.clouddn.com/pulldow-img.jpg">
          <span v-if="props.beforePullDown">{{ pullDownTip }}</span>
          <template v-else>
            <span v-if="props.isPullingDown">正在更新...</span>
            <span v-else>更新成功</span>
          </template>
        </div>
      </div>
    </template>
  </cube-scroll>
M
init  
miaodian 已提交
185 186
  ```
  ```javascript
T
tank0317 已提交
187 188 189 190 191 192 193
  data() {
    return {
      options: {
        pullDownRefresh: {
          threshold: 60,
          stop: 40,
          txt: '更新成功'
M
init  
miaodian 已提交
194
        }
T
tank0317 已提交
195 196 197 198 199 200 201 202 203 204 205 206
      },
      ...
    }
  },
  computed: {
    pullDownTip() {
      if (this.pullDownY <= 60) {
        return '下拉刷新...'
      } else if (this.pullDownY <= 90) {
        return '继续下拉有惊喜...'
      } else {
        return '松手得惊喜!'
M
init  
miaodian 已提交
207 208
      }
    },
T
tank0317 已提交
209 210
    headerStyle() {
      return Math.min(1, Math.max(0, 1 - this.pullDownY / 40))
M
init  
miaodian 已提交
211
    }
T
tank0317 已提交
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
  },
  methods: {
    onScrollHandle(pos) {
      this.pullDownY = pos.y
      if (pos.y > 0) {
        this.pullDownStyle = `top:${pos.y}px`
        this.triggerSurpriseFlag = false
        if (this.pullDownY > 90) {
          this.triggerSurpriseFlag = true
        }
      }
      this.$refs.topHeader.style.opacity = this.headerStyle
    },
    onPullingDown() {
      if (this.triggerSurpriseFlag) {
        this.triggerSurprise = true
        this.$refs.scroll.forceUpdate()
        return
      }
      setTimeout(() => {
        this.$refs.scroll.forceUpdate()
      }, 1000)
    },
    ...
M
init  
miaodian 已提交
236 237
  }
  ```
T
tank0317 已提交
238
  
F
fengweiyao 已提交
239
  通过作用域插槽提供的作用域参数,如:`beforePulldown``isPullingDown`,你可以根据状态的变化来控制动画流程,其他作用域参数及其含义详见下面的[插槽](#/zh-CN/docs/scroll#cube-插槽-anchor)。在一个完整的下拉刷新过程中,`beforePullDown``isPullingDown`的状态变化如下:
M
init  
miaodian 已提交
240

T
tank0317 已提交
241 242 243 244
  | 流程 | beforePulldown | isPullingDown | 备注 |
  | - | - | - | - |
  | 1. 未触发下拉刷新 | true | - | 展示继续下拉引导图案 |
  | 2. 触发下拉刷新 | false | true | 异步请求数据,显示 loading |
F
fengweiyao 已提交
245 246
  | 3. 获取数据成功 | false | false | 调用 `forceUpdate(true)`, 显示成功文案, 延迟 stopTime 时间进入步骤 4  |
  | 4. 下拉刷新完成 | true | - | - |
A
AmyFoxFN 已提交
247

F
fengweiyao 已提交
248
- **5. 高级使用 - 仿头条 App 首页**
M
init  
miaodian 已提交
249

F
fengweiyao 已提交
250
  Scroll 组件能够满足绝大多数移动端应用的滚动需求。本例中通过横向和纵向的两个 Scroll 组件快速实现了模仿头条 App 首页的滚动体验。完整的示例代码在[这里](https://github.com/didi/cube-ui/blob/master/example/pages/scroll/toutiao.vue)
A
AmyFoxFN 已提交
251

M
init  
miaodian 已提交
252
  ```html
T
tank0317 已提交
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
  <div class="nav-scroll-list-wrap">
    <cube-scroll ref="navScroll" direction="horizontal">
      <ul class="nav-wrapper">
        <li v-for="(item, index) in navTxts" :key="index" class="nav-item">{{ item }}</li>
      </ul>
    </cube-scroll>
    <div class="more-wrapper">
      <span class="more"></span>
    </div>
  </div>
  <div class="content-scroll-wrapper">
    <div class="content-scroll-list-wrap" ref="scrollWrapper">
      <cube-scroll
        ref="contentScroll"
        :data="content"
        :options="options"
        @pulling-down="onPullingDown"
        @pulling-up="onPullingUp">
        <ul class="imgs-wrapper">
          <li v-for="(item, index) in content" :key="index" class="imgs-item">
            <img :src="item.url">
          </li>
        </ul>
        <template slot="pulldown" slot-scope="props">
          <div v-if="props.pullDownRefresh"
            class="cube-pulldown-wrapper"
            :style="props.pullDownStyle">
            <div v-if="props.beforePullDown"
              class="before-trigger"
              :style="{paddingTop: props.bubbleY + 'px'}">
              <span :class="{rotate: props.bubbleY > options.pullDownRefresh.threshold - 60}"></span>
            </div>
            <div class="after-trigger" v-else>
              <div v-show="props.isPullingDown" class="loading">
                <cube-loading></cube-loading>
              </div>
              <transition name="success">
                <div v-show="!props.isPullingDown" class="text-wrapper"><span class="refresh-text">今日头条推荐引擎有x条更新</span></div>
              </transition>
            </div>
M
init  
miaodian 已提交
293
          </div>
T
tank0317 已提交
294 295 296 297
        </template>
      </cube-scroll>
    </div>
  </div>
M
init  
miaodian 已提交
298 299
  ```

T
tank0317 已提交
300 301
  和“仿京东 APP”示例不同的是,在下拉刷新的自定义动画中,使用了`pulldown`作用域插槽中的`pullDownStyle``bubbleY`更方便的实现下拉动画。

F
fengweiyao 已提交
302
  `pullDownStyle`用来控制下拉内容的位置,值为字符串`top: n px`(n 代表数值)。Scroll 组件是通过绝对定位的`top`值来控制下拉内容位置的。初始状态`top`值为负值,大小刚好为下拉内容的高度,因此下拉内容被隐藏到滚动区域上方,当下拉过程中,Scroll 组件会逐渐增大`top`值,实时更新下拉内容的位置。`top`最大值为0,即当下拉内容完全显示后`top`值不再增加。即 `pullY - height <= top <= 0`。(pullY 为下拉距离,height 为下拉内容高度)
T
tank0317 已提交
303

F
fengweiyao 已提交
304
  `bubbleY`用来辅助实现自定义动画。在默认动画中,`bubbleY`用来控制气泡尾巴长度;在头条例子中,用来控制箭头的`padding-top`值,间接控制箭头位置。`bubbleY`的最小值为 0,下拉过程中,当下拉距离大于下拉内容高度后,`bubbleY`开始增大。即 `0 <= bubbleY <= pullY - height`
T
tank0317 已提交
305

F
fengweiyao 已提交
306
  > 在本例中,`pullDownRefresh`配置项没有传入`stop`值,但是下拉后依然能够回弹到正确位置,原因是 Scroll 组件初始化时会将 `beforePullDown === false && isPullingDown === true` 时下拉内容高度作为 `stop` 默认值。
M
init  
miaodian 已提交
307 308 309 310 311 312 313

### Props 配置

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| - | - | - | - | - |
| data | 用于列表渲染的数据 | Array | - | [] |
| direction | 滚动方向 | String | 'vertical', 'horizontal' | 'vertical' |
A
Amy 已提交
314
| options | better-scroll 配置项,具体请参考[BS 官方文档](https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/options.html) | Object | - | {<br>  observeDOM: true,<br>  click: true,<br>  probeType: 1,<br>  scrollbar: false,<br>  pullDownRefresh: false,<br>  pullUpLoad: false<br>} |
D
dolymood 已提交
315 316 317
| scrollEvents<sup>1.9.0</sup> | 配置需要派发的 scroll 事件 | Array | 可包含子项:'scroll', 'before-scroll-start', 'scroll-end' | [] |
| listenScroll | 是否派发 scroll 事件。`即将废弃`,推荐使用 `scroll-events` 属性 | Boolean | true/false | false |
| listenBeforeScroll | 是否派发 before-scroll-start 事件。`即将废弃`,推荐使用 `scroll-events` 属性 | Boolean | true/false | false |
A
AmyFoxFN 已提交
318
| refreshDelay | data属性的数据更新后,scroll 的刷新延时 | Number | - | 20 |
M
init  
miaodian 已提交
319

A
AmyFoxFN 已提交
320 321
`options`中 better-scroll 的几个常用配置项,`scrollbar``pullDownRefresh``pullUpLoad`这三个配置即可设为 `Boolean``false` 关闭该功能,`true` 开启该功能,并使用默认子配置),也可设为`Object`,开启该功能并具体定制其子配置项。

A
AmyFoxFN 已提交
322
- `scrollbar` 子配置项
M
init  
miaodian 已提交
323 324 325 326 327

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| - | - | - | - | - |
| fade | 是否淡入淡出 | Boolean | true/false | false |

A
AmyFoxFN 已提交
328
- `pullDownRefresh` 子配置项
M
init  
miaodian 已提交
329 330 331 332

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| - | - | - | - | - |
| threshold | 下拉刷新动作的下拉距离阈值 | Number | - | 90 |
333 334
| stop | 回弹停留的位置 | Number | - | 组件会自动计算回弹时显示的元素高度作为默认值 |
| stopTime | 刷新成功的文案显示时间 | Number | - | 600 |
M
init  
miaodian 已提交
335 336
| txt | 刷新成功的文案 | String | - | 'Refresh success' |

A
AmyFoxFN 已提交
337
- `pullUpLoad` 子配置项
M
init  
miaodian 已提交
338 339 340 341

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| - | - | - | - | - |
| threshold | 上拉刷新动作的上拉距离阈值 | Number | - | 0 |
A
AmyFoxFN 已提交
342
| txt | 上拉加载的相关文案 | Object | - | { more: '', noMore: '' } |
M
init  
miaodian 已提交
343 344 345

### 插槽

D
dolymood 已提交
346
| 名字 | 说明 | 作用域参数 |
M
init  
miaodian 已提交
347
| - | - | - |
A
AmyFoxFN 已提交
348
| default | 基于`data`属性渲染的列表 | - |
U
ustbhuangyi 已提交
349
| pulldown | 位于列表上方,会在下拉刷新时显示 | pullDownRefresh: 是否开启了下拉刷新功能 <br> pullDownStyle: 移入移出的样式 <br> beforePullDown: 是否正在做下拉操作 <br> isPullingDown: 是否正在拉取数据 <br> bubbleY: 当前下拉的距离 - 50|
M
init  
miaodian 已提交
350 351 352 353 354 355 356
| pullup | 位于列表下方,会在上拉加载时显示 | pullUpLoad: 是否开启了上拉加载功能 <br> isPullUpLoad: 是否正在加载数据 |

### 事件

| 事件名 | 说明 | 参数 |
| - | - | - |
| click | 点击列表项时触发 | item - 该列表项的数据 |
A
Amy 已提交
357 358 359
| scroll | 当 `scroll-events` 包含 `scroll` 时,根据 probeType 的值决定派发时机 | Object {x, y} - 实时滚动位置的坐标 |
| before-scroll-start | 当 `scroll-events` 包含 `before-scroll-start` 时,在滚动开始之前触发 | - |
| scroll-end<sup>1.9.0</sup> | 当 `scroll-events` 包含 `scroll-end` 时,在滚动结束时触发 | Object {x, y} - 实时滚动位置的坐标 |
M
init  
miaodian 已提交
360 361
| pulling-down | 当 pullDownRefresh 属性为 true 时,在下拉超过阈值时触发 | - |
| pulling-up | 当 pullUpLoad 属性为 true 时,在上拉超过阈值时触发 | - |
T
tank0317 已提交
362 363 364 365 366 367

### 方法

| 方法名 | 说明 | 参数 |
| - | - | - |
| scrollTo | 滚动到指定位置 | x: 横向位置<br> y: 纵向位置<br> time: 过渡动画时间<br> ease: 动画曲线 |
F
fengweiyao 已提交
368
| forceUpdate | 标记上拉下拉结束,强制重新计算可滚动距离 | dirty: 是否有数据更新,默认为 false。true 表示有数据更新重新计算可滚动距离,上拉文案显示`pullUpLoad.text.more`值,false 表示没有数据更新,无需重新计算, 上拉文案显示`pullUpLoad.text.nomore`值 |
T
tank0317 已提交
369
| disable | 禁用滚动 | - |
F
fengweiyao 已提交
370
| enable | 启用滚动,默认是开启滚动的。 | - |
D
dolymood 已提交
371 372
| resetPullUpTxt | 当从无更多切换到有更多时,重置上拉文本内容 | - |
| refresh | 刷新,重新计算高度且刷新 BetterScroll 实例 | - |
F
fengweiyao 已提交
373 374 375 376 377 378

### 内部属性

| 属性名 | 说明 |
| - | - |
| scroll | 可以通过该属性获得内部实现滚动核心的 BScoll 实例,从而获得更多 BScoll 的底层能力,如监听`touchEnd`事件,获得滚动中的中间状态等,具体可查看[ better-scroll 文档](http://ustbhuangyi.github.io/better-scroll/doc/zh-hans/) |