BetterScroll 是什么

BetterScroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件。它的核心是借鉴的 iscroll (opens new window)的实现,它的 API 设计基本兼容 iscroll,在 iscroll 的基础上又扩展了一些 feature 以及做了一些性能优化。

BetterScroll 是使用纯 JavaScript 实现的,这意味着它是无依赖的。

官方文档:BetterScroll

官方Demo:示例

为什么不能滚动:滚动原理

原理图

绿色部分为 wrapper,也就是父容器,它会有固定的高度。黄色部分为 content,它是父容器的第一个子元素,它的高度会随着内容的大小而撑高。那么,当 content 的高度不超过父容器的高度,是不能滚动的,而它一旦超过了父容器的高度,我们就可以滚动内容区了,这就是 BetterScroll 的滚动原理。

在项目中使用

基本HTML结构

<div class="container">
  <header class="header-wrapper">
    <div class="header-content">
      <div class="header-content-item">动画</div>
      <div class="header-content-item">漫画</div>
      <div class="header-content-item">游戏</div>
      <div class="header-content-item">文学</div>
    </div>
  </header>
  <div class="wrapper">
    <div class="content">
      <span class="pullup-txt">Loading...</span>
    </div>
  </div>
</div>

样式

html,body
  margin: 0
  padding: 0
  background: #ccc
.container
  position: relative
  .header-wrapper
    header-wrapper-height = 40px
    background: red
    height: header-wrapper-height
    width: 100%
    white-space: nowrap
    overflow: hidden
    .header-content
      display: inline-block
      padding: 0 10px
      box-sizing: border-box
      .header-content-item
        display: inline-block
        width: 125px
        height: 100%
        line-height: header-wrapper-height
  .wrapper
    position: fixed
    top: 45px
    bottom: 10px
    height: auto
    width: 100%
    // background: green
    overflow: hidden
    .content
      // position: absolute
      padding: 0 10px
      box-sizing: border-box
      .pullup-txt
        display: none
        text-align: center
        display: block
        font-size: 17px
        color: white
      .content-item
        width: 100%
        background: white
        height: 100px
        display: flex
        align-items: center
        padding: 0 10px
        box-sizing: border-box
        margin-bottom: 10px
        border-radius: 10px
        .content-item-avatar
          width: 50px
          height: 50px
          img
            width: 50px
            height: 50px
            border-radius: 50%
        .content-item-body
          margin-left: 10px

JavaScript逻辑

import '../style/index/index.styl'
import 'lib-flexible'
import $ from 'jquery'
// 导入better-scroll核心组件
import BScroll from '@better-scroll/core'
import Pullup from '@better-scroll/pull-up'
import ObserveDOM from '@better-scroll/observe-dom'
BScroll.use(ObserveDOM)
BScroll.use(Pullup)
let bodyScroll
let timer
let number = 0
const maxNumber = 10
$(function () {
  // 头部滑动
  let headerWrapper = document.querySelector('.header-wrapper')
  let headerScroll = new BScroll(headerWrapper, {
    scrollX: true,
    scrollY: false,
    probeType: 3 // listening scroll event
  })
  // 内容区滑动
  let wrapper = document.querySelector('.wrapper')
  bodyScroll = new BScroll(wrapper, {
    scrollY: true,
    probeType: 3, // listening scroll event
    tap: 'tap',
    // 上拉加载更多示例
    pullUpLoad: true,
    ObserveDOM: true
  })

  bodyScroll.on('pullingUp', pullingUpHandler)
  bodyScroll.autoPullUpLoad()
})
function pullingUpHandler() {
  $('.pullup-txt').show()
  clearTimeout(timer)
  timer = setTimeout(async () => {
    number++
    if (number >= maxNumber) {
      // 假设没有数据了
      $('.pullup-txt').text('没有数据了!')
      bodyScroll.refresh()
      bodyScroll.closePullUp()
    } else {
      const result = await getSaid()
      $('.pullup-txt').before(render(result))
      bodyScroll.refresh()
      bodyScroll.finishPullUp()
      $('.pullup-txt').hide()
    }
  }, 1000)
}
async function getSaid(c) {
  const result = await $.get('https://v1.hitokoto.cn/', {
    c
  })
  return result.hitokoto
}
function render(text) {
  return `<div class="content-item">
            <div class="content-item-avatar">
              <img
                src="https://cdn.jsdelivr.net/npm/kang-static@latest/avatar.jpg"
              />
            </div>
            <div class="content-item-body">${text}</div>
          </div>`
}

在线Demo

使用注意点

  1. 父容器需小于滚动容器才可以滚动
  2. 下拉刷新,上拉加载等需要安装对应插件