下拉刷新

下拉刷新是一个特殊组件,可用于启动页面内容的刷新。

下拉刷新布局

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

<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>

Where:

从底部下拉刷新

也可以使其像从底部下拉一样工作。在这种情况下,我们需要将元素移动到页面内容的底部,并添加额外的ptr-preloader element to the bottom of page content and add additional 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类。在 "refreshing" 状态下,箭头将被隐藏,用户将看到预加载器指示器。在这个阶段,您可能需要执行 Ajax 请求并刷新页面内容。

下拉刷新应用方法

有几个与应用程序下拉刷新容器一起使用的方法:

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

  • el - HTMLElement字符串(使用 CSS 选择器)- PTR 元素ptr-content。必需。

方法返回创建的 PTR 实例

仅在您在页面初始化后添加了 ptr 内容或如果您想稍后启用它的情况下使用此方法。否则,如果页面初始化时存在 "ptr-content" 元素,它将自动创建

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

  • el - HTMLElement字符串(使用 CSS 选择器)- PTR 元素ptr-content。必需。

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

  • el - HTMLElement字符串(使用 CSS 选择器)。PTR 元素ptr-content)中

方法返回 PTR 实例

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

  • el - HTMLElement字符串(使用 CSS 选择器)。PTR 元素ptr-content。必需。

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

  • el - HTMLElement字符串(使用 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 元素的 Dom7 实例ptr-content)
方法
ptr.done()重置 PTR 状态
ptr.refresh()触发 PTR
ptr.destroy()销毁 PTR 实例并从指定的 HTML 元素中移除 PTR 事件监听器

下拉刷新事件

PTR 将在弹出元素上触发以下 DOM 事件,并在应用程序和弹出实例上触发事件:

DOM 事件

事件Target描述
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.

事件Target参数描述
pullStartptr(el)当您开始移动下拉刷新内容时,将触发此事件。作为参数,事件处理程序接收 ptr 元素
ptrPullStartapp(el)
pullMoveptr(el, data)在您移动下拉刷新内容期间,将触发此事件。作为参数,事件处理程序接收 ptr 元素和 ptr 数据,其中包含以下属性:
  • event- touchmove 事件
  • scrollTop- 当前滚动顶部位置
  • translate- 当前 translateY 偏移
  • touchesDiff- 触摸差异(以 px 为单位)
ptrPullMoveapp(el, data)
pullEndptr(el, data)当您释放下拉刷新内容时,将触发此事件。作为参数,事件处理程序接收 ptr 元素
ptrPullEndapp(el, data)
refreshptr(el, done)当下拉刷新进入 "refreshing" 状态时,将触发此事件。作为参数,事件处理程序接收 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>