下拉刷新

下拉刷新是一个特殊组件,可用来发起对页面内容的刷新。

下拉刷新布局

让我们了解如何将下拉刷新集成到页面中

<div class="page">
  <!-- Page content must have additional "ptr-content" class -->
  <div class="page-content ptr-content" data-ptr-distance="55" data-ptr-mousewheel="true">
    <!-- Default pull to refresh preloader-->
    <div class="ptr-preloader">
      <div class="preloader"></div>
      <div class="ptr-arrow"></div>
    </div>

    <!-- usual content below -->
    <div class="list">
      ...
    </div>

    <!-- nested scrollable element -->
    <div class="my-scolling-content ptr-watch-scrollable">
      ...
    </div>

    <!-- another nested scrollable element -->
    <div class="another-scolling-content ptr-ignore">
      ...
    </div>
  </div>
</div>

其中

从底部下拉刷新

也可以将其设置为从底部下拉。在这种情况下,我们需要将 ptr-preloader 元素移动到页面内容的底部,并添加其他 ptr-bottom 类,以下拉刷新内容

<div class="page">
  <!-- ptr-content must have additional "ptr-bottom" class -->
  <div class="page-content ptr-content ptr-bottom">
    <div class="list">
      ...
    </div>

    <!-- Pull to refresh preloader moves to bottom -->
    <div class="ptr-preloader">
      <div class="preloader"></div>
      <div class="ptr-arrow"></div>
    </div>
  </div>
</div>

下拉刷新序列

当用户开始向下下拉 ptr-content 时,ptr-preloader 会收到其他 ptr-pull-down 类。

当用户向下下拉 ptr-content 的距离超过 44px 时(当 ptr-preloader 完全可见时),ptr-preloader 将收到其他 ptr-pull-up 类,该类会更改箭头的旋转方向,以通知用户有关释放时的刷新操作。

当用户在处于“ptr-pull-up”状态时释放下拉刷新内容时,ptr-preloader 将收到其他 ptr-refreshing 类。在“刷新”状态下,箭头将隐藏,用户将看到预加载器指标。在此阶段,您可能需要进行 Ajax 请求并刷新页面内容。

下拉刷新应用程序方法

可以使用下拉刷新容器的几个应用程序方法

app.ptr.create(el)- 在指定的 HTML 元素容器上初始化 PTR。

  • el - HTMLElementstring (含 CSS 选择器) - PTR 元素 (ptr-content)。必需。

方法返回创建的 PTR 实例

仅在页面初始化后添加了 PTR 内容或之后希望启用 PTR 内容时使用此方法。否则,如果页面初始化上有“ptr-content”元素,则会自动创建

app.ptr.destroy(el)- 从指定的 HTML 元素移除 PTR 事件侦听器

  • el - HTMLElementstring (含 CSS 选择器) - PTR 元素 (ptr-content)。必需。

app.ptr.get(el)- 按照 HTML 元素获取 PTR 实例

  • el - HTMLElementstring (含 CSS 选择器)。PTR 元素 (ptr-content)。

方法返回 PTR 实例

app.ptr.done(el) - 重置指定 PTR 内容元素上的 PTR 状态

  • el - HTMLElementstring(带 CSS 选择器)。PTR 元素(ptr-content)。必填。

app.ptr.refresh(el) - 触发指定 PTR 内容元素上的 PTR

  • el - HTMLElementstring(带 CSS 选择器)。PTR 元素(ptr-content)。必填。

下拉刷新方法和属性

如果我们手动创建了 PTR 或使用了 app.ptr.get 方法,我们将初始化 PTR 实例,其中包含有用的方法和属性

// init ptr manually
var ptr = app.ptr.create('.ptr-content');

// or using get to retrieve already created instance
var ptr = app.ptr.get('.ptr-content');
属性
ptr.app链接到全局应用实例
ptr.elPTR HTML 元素(ptr-content
ptr.$el具有 PTR HTML 元素(ptr-content)的 Dom7 实例
方法
ptr.done()重置 PTR 状态
ptr.refresh()触发 PTR
ptr.destroy()销毁 PTR 实例,并删除指定 HTML 元素上的 PTR 事件侦听器

下拉刷新事件

PTR 将在弹出元素以及应用和弹出实例上触发以下 DOM 事件

DOM 事件

事件目标描述
ptr:pullstart下拉刷新内容<div class="ptr-content">当你开始移动下拉刷新内容时,此事件将触发
ptr:pullmove下拉刷新内容<div class="ptr-content">当你移动下拉刷新内容时,此事件将触发
ptr:pullend下拉刷新内容<div class="ptr-content">当你释放下拉刷新内容时,此事件将触发
ptr:refresh下拉刷新内容<div class="ptr-content">当下拉刷新进入“refreshing”状态时,将触发此事件。event.detail 包含要加载完成之后重置其状态的 ptr.done 方法
ptr:done下拉刷新内容<div class="ptr-content">下拉刷新完成后,即它返回到初始状态后(调用 ptr.done 方法之后),将触发此事件
ptr:beforedestroy下拉刷新内容<div class="ptr-content">此事件将在 PTR 实例被销毁之前触发

应用和下拉刷新实例事件

PTR 实例同时在自身实例和应用实例上触发事件。应用实例事件具有相同名称,前缀为 ptr

事件目标参数描述
pullStartptr(el)当你开始移动下拉刷新内容时,此事件将触发。作为参数,事件处理程序接收 ptr 元素
ptrPullStartapp(el)
pullMoveptr(el, data)当你移动下拉刷新内容时,此事件将触发。作为参数,事件处理程序接收 ptr 元素和包含以下属性的 ptr 数据
  • event - touchmove 事件
  • scrollTop - 当前滚动顶部位置
  • translate - 当前 translateY 偏移量
  • touchesDiff - 触摸差异(以像素为单位)
ptrPullMoveapp(el, data)
pullEndptr(el, data)当你释放下拉刷新内容时,此事件将触发。作为参数,事件处理程序接收 ptr 元素
ptrPullEndapp(el, data)
refreshptr(el, done)下拉刷新进入“刷新”状态时将触发事件。事件处理程序会收到一个 ptr 元素和一个 done 函数作为参数,用于重置 PTR 状态
ptrRefreshapp(el, done)
doneptr(el)下拉刷新完成并返回初始状态后(调用了 ptr.done 方法后),将触发事件。事件处理程序会收到一个 ptr 元素作为参数
ptrDoneapp(el)
beforeDestroyptr(ptr)PTR 实例即将被销毁之前会触发事件。事件处理程序会收到一个 PTR 实例作为参数
ptrBeforeDestroyapp(ptr)

CSS 变量

下面是相关的 CSS 变量(CSS 自定义属性)列表。

.ios {
  --f7-ptr-preloader-size: 28px;
  --f7-ptr-size: 44px;
}
.md {
  --f7-ptr-preloader-size: 22px;
  --f7-ptr-size: 40px;
}
.md,
.md .dark,
.md [class*='color-'] {
  --f7-ptr-preloader-bg-color: var(--f7-md-surface-1);
  --f7-ptr-preloader-color: var(--f7-md-primary);
}

示例

从顶部拉动

pull-to-refresh.f7.html
<template>
  <div class="page">
    <div class="navbar">
      <div class="navbar-bg"></div>
      <div class="navbar-inner">
        <div class="title">Pull To Refresh</div>
      </div>
    </div>
    <div class="page-content ptr-content" @ptr:refresh=${loadMore}>
      <div class="ptr-preloader">
        <div class="preloader"></div>
        <div class="ptr-arrow"></div>
      </div>
      <div class="list media-list">
        <ul>
          ${items.map((item) => $h`
          <li class="item-content">
            <div class="item-media"><img src=${item.picURL} width="44" /></div>
            <div class="item-inner">
              <div class="item-title-row">
                <div class="item-title">${item.song}</div>
              </div>
              <div class="item-subtitle">${item.author}</div>
            </div>
          </li>
          `)}
        </ul>
      </div>
    </div>
  </div>
</template>
<script>
  export default (props, { $update }) => {
    // Dummy Content
    const songs = ['Yellow Submarine', 'Don\'t Stop Me Now', 'Billie Jean', 'Californication'];
    const authors = ['Beatles', 'Queen', 'Michael Jackson', 'Red Hot Chili Peppers'];
    let items = [
      {
        picURL: 'https://cdn.framework7.io/placeholder/abstract-88x88-1.jpg',
        song: 'Yellow Submarine',
        author: 'Beatles',
      },
      {
        picURL: 'https://cdn.framework7.io/placeholder/abstract-88x88-2.jpg',
        song: 'Don\'t Stop Me Now',
        author: 'Queen',
      },
      {
        picURL: 'https://cdn.framework7.io/placeholder/abstract-88x88-3.jpg',
        song: 'Billie Jean',
        author: 'Michael Jackson',
      },
    ]

    const loadMore = (e, done) => {
      // Emulate 2s loading
      setTimeout(() => {
        const picURL = 'https://cdn.framework7.io/placeholder/abstract-88x88-' + (Math.floor(Math.random() * 10) + 1) + '.jpg';
        const song = songs[Math.floor(Math.random() * songs.length)];
        const author = authors[Math.floor(Math.random() * authors.length)];
        // Add new item
        items.push({
          picURL,
          song,
          author,
        });

        // Update state to rerender
        $update();

        // When loading done, we need to reset it
        done();
      }, 2000);
    }

    return $render;
  }
</script>

从底部拉动

pull-to-refresh-bottom.f7.html
<template>
  <div class="page">
    <div class="navbar">
      <div class="navbar-bg"></div>
      <div class="navbar-inner">
        <div class="title">Pull To Refresh Bottom</div>
      </div>
    </div>
    <div class="page-content ptr-content ptr-bottom" @ptr:refresh=${loadMore}>
      <div class="ptr-preloader">
        <div class="preloader"></div>
        <div class="ptr-arrow"></div>
      </div>
      <div class="list media-list">
        <ul>
          ${items.map((item) => $h`
          <li class="item-content">
            <div class="item-media"><img src=${item.picURL} width="44" /></div>
            <div class="item-inner">
              <div class="item-title-row">
                <div class="item-title">${item.song}</div>
              </div>
              <div class="item-subtitle">${item.author}</div>
            </div>
          </li>
          `)}
        </ul>
      </div>
    </div>
  </div>
</template>
<script>
  export default (props, { $update }) => {
    // Dummy Content
    const songs = ['Yellow Submarine', 'Don\'t Stop Me Now', 'Billie Jean', 'Californication'];
    const authors = ['Beatles', 'Queen', 'Michael Jackson', 'Red Hot Chili Peppers'];
    let items = [
      {
        picURL: 'https://cdn.framework7.io/placeholder/abstract-88x88-1.jpg',
        song: 'Yellow Submarine',
        author: 'Beatles',
      },
      {
        picURL: 'https://cdn.framework7.io/placeholder/abstract-88x88-2.jpg',
        song: 'Don\'t Stop Me Now',
        author: 'Queen',
      },
      {
        picURL: 'https://cdn.framework7.io/placeholder/abstract-88x88-3.jpg',
        song: 'Billie Jean',
        author: 'Michael Jackson',
      },
    ]

    const loadMore = (e, done) => {
      // Emulate 2s loading
      setTimeout(() => {
        const picURL = 'https://cdn.framework7.io/placeholder/abstract-88x88-' + (Math.floor(Math.random() * 10) + 1) + '.jpg';
        const song = songs[Math.floor(Math.random() * songs.length)];
        const author = authors[Math.floor(Math.random() * authors.length)];
        // Add new item
        items.push({
          picURL,
          song,
          author,
        });

        // Update state to rerender
        $update();

        // When loading done, we need to reset it
        done();
      }, 2000);
    }

    return $render;
  }
</script>