Swipeout(可滑动列表)
Swipeout 是 列表视图 的扩展,允许您在列表元素上滑动以显示隐藏的菜单,其中包含可用的操作,例如滑动以删除。
Swipeout 布局
让我们看看列表视图中 Swipeout 元素的布局结构
<div class="list">
<ul>
<!-- Additional "swipeout" class on li -->
<li class="swipeout">
<!-- Usual list element wrapped with "swipeout-content" -->
<div class="swipeout-content">
<!-- Your list element here -->
<div class="item-content">
<div class="item-media">...</div>
<div class="item-inner">...</div>
</div>
</div>
<!-- Swipeout actions left -->
<div class="swipeout-actions-left">
<!-- Swipeout actions links/buttons -->
<a href="#">Action 1</a>
<a href="#">Action 2</a>
</div>
<!-- Swipeout actions right -->
<div class="swipeout-actions-right">
<!-- Swipeout actions links/buttons -->
<a href="#" class="swipeout-close">Action 1</a>
<a href="#" class="swipeout-delete">Delete</a>
</div>
</li>
...
</ul>
</div>
其中
swipeout-content
- 列表元素的包装器。此容器将在您滑动列表项时移动。swipeout-actions-left
- 包含左侧 Swipeout 操作按钮/链接的容器swipeout-actions-right
- 包含右侧 Swipeout 操作按钮/链接的容器swipeout-close
- Swipeout 链接上的附加类,当您单击此链接时将关闭 Swipeout 元素swipeout-delete
- Swipeout 链接上的附加类,当您单击此链接时将删除 Swipeout 列表项
请注意,swipeout-content
和 swipeout-actions-left/right
应该是 <li> 的直接子元素
如果您只有 "item-content",您可以通过将 "item-content" 类添加到 "swipeout-content" 来简化布局
<li class="swipeout">
<div class="swipeout-content item-content">
<div class="item-media">...</div>
<div class="item-inner">...</div>
</div>
<div class="swipeout-actions-right">
<a href="#">Action 1</a>
<a href="#">Action 2</a>
</div>
</li>
如果您使用 链接项,布局将如下所示
<li class="swipeout">
<div class="swipeout-content">
<a href="#" class="item-content item-link">
<div class="item-media">...</div>
<div class="item-inner">...</div>
</a>
</div>
<div class="swipeout-actions-right">
<a href="#">Action 1</a>
<a href="#">Action 2</a>
</div>
</li>
滑动以删除
Framework7 默认支持此常用功能,无需一行 JavaScript 代码。您只需要将 swipeout-delete
类添加到 Swipeout 操作按钮即可
<li class="swipeout">
<div class="swipeout-content item-content">
<div class="item-media">...</div>
<div class="item-inner">...</div>
</div>
<div class="swipeout-actions-right">
<!-- Add this button and item will be deleted automatically -->
<a href="#" class="swipeout-delete">Delete</a>
</div>
</li>
当用户点击 "删除" 按钮时,还可以调用确认模态框,只有在确认后才会删除元素。为了确认删除,您需要将额外的 data-confirm
和 data-confirm-title
(可选)属性添加到删除链接中
<li class="swipeout">
<div class="swipeout-content item-content">
<div class="item-media">...</div>
<div class="item-inner">...</div>
</div>
<div class="swipeout-actions-right">
<!-- We add data-confirm and data-confirm-title attributes -->
<a href="#" class="swipeout-delete" data-confirm="Are you sure want to delete this item?" data-confirm-title="Delete?">Delete</a>
</div>
</li>
过度滑动
Swipeout 还支持 "过度滑动" 操作,如果您过度滑动操作,这些操作将自动触发。在这种情况下,我们需要将 swipeout-overswipe
类添加到所需操作按钮
<li class="swipeout">
<div class="swipeout-content item-content">
<div class="item-media">...</div>
<div class="item-inner">...</div>
</div>
<div class="swipeout-actions-right">
<a href="#">More</a>
<a href="#" class="swipeout-delete swipeout-overswipe">Delete</a>
</div>
</div>
</li>
过度滑动 只能用于右侧 Swipeout 操作中的最后一个按钮,以及左侧 Swipeout 操作中的第一个按钮。
使用过度滑动,脚本将自动在过度滑动按钮上触发 "click" 事件,因此您需要为此按钮添加适当的事件监听器
过度滑动按钮在过度滑动期间将具有额外的
swipeout-overswipe-active
类,您可以使用它来对这种状态进行额外的样式设置
<li class="swipeout">
<div class="swipeout-content">
<a href="#" class="item-content item-link">
...
</a>
</div>
<div class="swipeout-actions-left">
<a href="#" class="swipeout-overswipe bg-green reply">Reply</a>
<a href="#" class="bg-blue forward">Forward</a>
</div>
<div class="swipeout-actions-right">
<a href="#" class="mark bg-orange">Mark</a>
<a href="#" class="swipeout-delete swipeout-overswipe">Delete</a>
</div>
</li>
Swipeout 应用方法
Swipeout 还具有丰富的 JavaScript API,允许您控制 Swipeout 元素。让我们看看相应的应用方法
app.swipeout.open(el, side, callback) - 在指定元素上显示 Swipeout 操作
- el - HTMLElement 或 string(带 CSS 选择器)的列表 (<li>) 元素,带有 "swipeout" 类。必需
- side - string(可以是 "left" 或 "right")要打开的 Swipeout 操作。如果项目同时具有左侧和右侧 Swipeout 操作,则应指定。可选
- callback - function - 回调函数将在 Swipeout 元素完成其打开动画后执行
app.swipeout.close(el, callback) - 在指定元素上关闭 Swipeout 操作
- el - HTMLElement 或 string(带 CSS 选择器)的列表 (<li>) 元素,带有 "swipeout" 类。必需
- callback - function - 回调函数将在 Swipeout 元素完成其关闭动画后执行
app.swipeout.delete(el, callback) - 删除指定的 Swipeout 元素
- el - HTMLElement 或 string(带 CSS 选择器)的列表 (<li>) 元素,带有 "swipeout" 类。必需
- callback - function - 回调函数将在 Swipeout 元素完成其删除动画后执行,然后它将从 DOM 中删除
app.swipeout.el - 属性。当前打开的 Swipeout HTMLElement。或者如果未打开任何 Swipeout 元素,则为 undefined
Swipeout 应用参数
通过在 swipeout
属性下传递与 Swipeout 相关的参数,可以在应用程序初始化时配置全局 Swipeout 行为。
参数 | 类型 | 默认值 | 描述 |
---|---|---|---|
noFollow | boolean | false | 在旧/慢速设备上可能更好的性能的备用选项。如果您启用它,则 Swipeout 项在触摸时不会跟随您的手指,而是在向左/右滑动时自动打开/关闭。 |
removeElements | boolean | boolean | true |
如果禁用,则框架不会在 "swipeout-delete" 点击时从 DOM 中删除 Swipeout 元素。如果使用 Vue 或 React 等其他库来管理(删除)Swipeout 项目,则很有用 | boolean | false | removeElementsWithTimeout |
boolean | false | 0 | 如果启用,则框架将在指定延迟后在 "swipeout-delete" 点击时从 DOM 中删除 Swipeout 元素 |
removeElementsTimeout | false | 1.2 | number |
0
var app = new Framework7({
swipeout: {
noFollow: true,
removeElements: false
}
});
如果 removeElementsWithTimeout
启用,则删除 Swipeout 项目的延迟(毫秒)。
overswipeRatio
number
1.2 | 定义触发过度滑动需要滑动多少/多用力(默认值为 1.2) | 描述 |
---|---|---|
要更改这些参数,我们需要在应用程序初始化时在 swipeout 属性下传递它们,例如 | Swipeout 事件 | Swipeout 将触发以下 DOM 事件和应用程序实例上的事件 |
DOM 事件 | Swipeout 事件 | 事件 |
目标 | Swipeout 事件 | swipeout |
Swipeout 元素<li class="swipeout"> | Swipeout 事件 | 当您移动 Swipeout 元素时,将触发事件。event.detail 包含当前打开进度百分比 |
swipeout:open | Swipeout 事件 | 当 Swipeout 元素开始其打开动画时,将触发事件 |
swipeout:opened | Swipeout 事件 | 当 Swipeout 元素完成其打开动画时,将触发事件 |
swipeout:close | Swipeout 事件 | 当 Swipeout 元素开始其关闭动画时,将触发事件 |
swipeout:closed | Swipeout 事件 | 当 Swipeout 元素完成其关闭动画时,将触发事件 |
swipeout:delete | Swipeout 事件 | 当 Swipeout 元素开始其删除动画时,将触发事件 |
swipeout:deleted
当 Swipeout 元素完成其删除动画后,它将从 DOM 中删除之前,将触发事件
1.2 | 定义触发过度滑动需要滑动多少/多用力(默认值为 1.2) | swipeout:overswipeenter | 描述 |
---|---|---|---|
要更改这些参数,我们需要在应用程序初始化时在 swipeout 属性下传递它们,例如 | 当启用过度滑动时,将触发事件 | swipeout:overswipeexit | 当禁用过度滑动时,将触发事件 |
应用程序实例事件 | 当启用过度滑动时,将触发事件 | Swipeout 实例在应用程序实例上发出事件。 | 事件 |
参数 | 当启用过度滑动时,将触发事件 | Swipeout 实例在应用程序实例上发出事件。 | swipeout |
app | 当启用过度滑动时,将触发事件 | Swipeout 实例在应用程序实例上发出事件。 | 当您移动 Swipeout 元素时,将触发事件。event.detail 包含当前打开进度百分比 |
progress | 当启用过度滑动时,将触发事件 | Swipeout 实例在应用程序实例上发出事件。 | 当 Swipeout 元素开始其打开动画时,将触发事件 |
当您移动 Swipeout 元素时,将触发事件 | 当启用过度滑动时,将触发事件 | Swipeout 实例在应用程序实例上发出事件。 | 当 Swipeout 元素完成其打开动画时,将触发事件 |
swipeoutOpen | 当启用过度滑动时,将触发事件 | Swipeout 实例在应用程序实例上发出事件。 | 当 Swipeout 元素开始其关闭动画时,将触发事件 |
swipeoutEl | 当启用过度滑动时,将触发事件 | Swipeout 实例在应用程序实例上发出事件。 | 当 Swipeout 元素完成其关闭动画时,将触发事件 |
swipeoutOpened | 当启用过度滑动时,将触发事件 | Swipeout 实例在应用程序实例上发出事件。 | 当 Swipeout 元素开始其删除动画时,将触发事件 |
CSS 变量
swipeoutClose
:root {
--f7-swipeout-delete-button-bg-color: #ff3b30;
--f7-swipeout-button-text-color: #fff;
--f7-swipeout-button-padding-vertical: 0px;
--f7-swipeout-button-bg-color: rgba(0, 0, 0, 0.22);
}
:root .dark,
:root.dark {
--f7-swipeout-button-bg-color: rgba(255, 255, 255, 0.55);
}
.ios {
--f7-swipeout-button-padding-horizontal: 30px;
--f7-swipeout-button-font-size: inherit;
--f7-swipeout-button-font-weight: inherit;
}
.md {
--f7-swipeout-button-padding-horizontal: 24px;
--f7-swipeout-button-font-size: 14px;
--f7-swipeout-button-font-weight: 500;
}
.md .dark,
.md.dark {
--f7-swipeout-button-text-color: #000;
}
swipeoutClosed
<template>
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner sliding">
<div class="title">Swipeout</div>
</div>
</div>
<div class="page-content">
<div class="block">
<p>
Swipe out actions on list elements is one of the most awesome F7 features. It allows you to call hidden menu
for each list element where you can put default ready-to use delete button or any other buttons for some
required actions.
</p>
</div>
<div class="block-title">Swipe to delete with confirm modal</div>
<div class="list list-strong list-outline-ios list-dividers-ios inset-md">
<ul>
<li class="swipeout">
<div class="item-content swipeout-content">
<div class="item-media"><i class="icon icon-f7"></i>
</div>
<div class="item-inner">
<div class="item-title">Swipe left on me please</div>
</div>
</div>
<div class="swipeout-actions-right">
<a data-confirm="Are you sure you want to delete this item?" class="swipeout-delete">Delete</a>
</div>
</li>
<li class="swipeout">
<div class="item-content swipeout-content">
<div class="item-media"> <i class="icon icon-f7"></i>
</div>
<div class="item-inner">
<div class="item-title">Swipe left on me too</div>
</div>
</div>
<div class="swipeout-actions-right">
<a data-confirm="Are you sure you want to delete this item?" class="swipeout-delete">Delete</a>
</div>
</li>
<li>
<div class="item-content">
<div class="item-media">
<i class="icon icon-f7"></i>
</div>
<div class="item-inner">
<div class="item-title">I am not removable</div>
</div>
</div>
</li>
</ul>
</div>
<div class="block-title">Swipe to delete without confirm</div>
<div class="list list-strong list-outline-ios list-dividers-ios inset-md">
<ul>
<li class="swipeout">
<div class="item-content swipeout-content">
<div class="item-inner">
<div class="item-title">Swipe left on me please</div>
</div>
</div>
<div class="swipeout-actions-right">
<a class="swipeout-delete">Delete</a>
</div>
</li>
<li class="swipeout">
<div class="item-content swipeout-content">
<div class="item-inner">
<div class="item-title">Swipe left on me too</div>
</div>
</div>
<div class="swipeout-actions-right">
<a class="swipeout-delete">Delete</a>
</div>
</li>
<li>
<div class="item-content">
<div class="item-inner">
<div class="item-title">I am not removable</div>
</div>
</div>
</li>
</ul>
</div>
<div class="block-title">Swipe for actions</div>
<div class="list list-strong list-outline-ios list-dividers-ios inset-md">
<ul>
<li class="swipeout">
<div class="item-content swipeout-content">
<div class="item-media">
<i class="icon icon-f7"></i>
</div>
<div class="item-inner">
<div class="item-title">Swipe left on me please</div>
</div>
</div>
<div class="swipeout-actions-right">
<a @click=${more}>More</a>
<a class="swipeout-delete">Delete</a>
</div>
</li>
<li class="swipeout">
<div class="item-content swipeout-content">
<div class="item-media">
<i class="icon icon-f7"></i>
</div>
<div class="item-inner">
<div class="item-title">Swipe left on me too</div>
</div>
</div>
<div class="swipeout-actions-right">
<a @click=${more}>More</a>
<a class="swipeout-delete">Delete</a>
</div>
</li>
<li class="swipeout">
<div class="item-content swipeout-content">
<div class="item-media">
<i class="icon icon-f7"></i>
</div>
<div class="item-inner">
<div class="item-title">You can't delete me</div>
</div>
</div>
<div class="swipeout-actions-right">
<a @click=${more}>More</a>
</div>
</li>
</ul>
</div>
<div class="block-title">With callback on remove</div>
<div class="list list-strong list-outline-ios list-dividers-ios inset-md">
<ul>
<li class="swipeout" @swipeout:deleted=${onDeleted}>
<div class="item-content swipeout-content">
<div class="item-inner">
<div class="item-title">Swipe left on me please</div>
</div>
</div>
<div class="swipeout-actions-right">
<a class="swipeout-delete">Delete</a>
</div>
</li>
<li class="swipeout" @swipeout:deleted=${onDeleted}>
<div class="item-content swipeout-content">
<div class="item-inner">
<div class="item-title">Swipe left on me too</div>
</div>
</div>
<div class="swipeout-actions-right">
<a class="swipeout-delete">Delete</a>
</div>
</li>
<li>
<div class="item-content">
<div class="item-inner">
<div class="item-title">I am not removable</div>
</div>
</div>
</li>
</ul>
</div>
<div class="block-title">With actions on left side (swipe to right)</div>
<div class="list list-strong list-outline-ios list-dividers-ios inset-md">
<ul>
<li class="swipeout">
<div class="item-content swipeout-content">
<div class="item-media">
<i class="icon icon-f7"></i>
</div>
<div class="item-inner">
<div class="item-title">Swipe right on me please</div>
</div>
</div>
<div class="swipeout-actions-left">
<a class="color-green" @click=${reply}>Reply</a>
<a class="color-blue" @click=${forward}>Forward</a>
</div>
</li>
<li class="swipeout">
<div class="item-content swipeout-content">
<div class="item-media">
<i class="icon icon-f7"></i>
</div>
<div class="item-inner">
<div class="item-title">Swipe right on me too</div>
</div>
</div>
<div class="swipeout-actions-left">
<a class="color-green" @click=${reply}>Reply</a>
<a class="color-blue" @click=${forward}>Forward</a>
</div>
</li>
</ul>
</div>
<div class="block-title">On both sides with overswipes</div>
<div class="list media-list list-strong list-outline-ios list-dividers-ios inset-md">
<ul>
<li class="swipeout">
<div class="swipeout-content">
<a class="item-link item-content">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">Facebook</div>
<div class="item-after">17:14</div>
</div>
<div class="item-subtitle">New messages from John Doe</div>
<div class="item-text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sagittis tellus ut turpis
condimentum, ut dignissim lacus tincidunt. Cras dolor metus, ultrices condimentum sodales sit amet,
pharetra sodales eros. Phasellus vel felis tellus. Mauris rutrum ligula nec dapibus feugiat. In vel
dui laoreet, commodo augue id, pulvinar lacus.
</div>
</div>
</a>
</div>
<div class="swipeout-actions-left">
<a class="color-green swipeout-overswipe" @click=${reply}>Reply</a>
<a class="color-blue" @click=${forward}>Forward</a>
</div>
<div class="swipeout-actions-right">
<a @click=${more}>More</a>
<a class="color-orange" @click=${mark}>Mark</a>
<a data-confirm="Are you sure you want to delete this item?"
class="swipeout-delete swipeout-overswipe">Delete</a>
</div>
</li>
<li class="swipeout">
<div class="swipeout-content">
<a class="item-link item-content">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">John Doe (via Twitter)</div>
<div class="item-after">17:11</div>
</div>
<div class="item-subtitle">John Doe (@_johndoe) mentioned you on Twitter!</div>
<div class="item-text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sagittis tellus ut turpis
condimentum, ut dignissim lacus tincidunt. Cras dolor metus, ultrices condimentum sodales sit amet,
pharetra sodales eros. Phasellus vel felis tellus. Mauris rutrum ligula nec dapibus feugiat. In vel
dui laoreet, commodo augue id, pulvinar lacus.
</div>
</div>
</a>
</div>
<div class="swipeout-actions-left">
<a class="color-green swipeout-overswipe" @click=${reply}>Reply</a>
<a class="color-blue" @click=${forward}>Forward</a>
</div>
<div class="swipeout-actions-right">
<a @click=${more}>More</a>
<a class="color-orange" @click=${mark}>Mark</a>
<a data-confirm="Are you sure you want to delete this item?"
class="swipeout-delete swipeout-overswipe">Delete</a>
</div>
</li>
<li class="swipeout">
<div class="swipeout-content">
<a class="item-link item-content">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">Facebook</div>
<div class="item-after">16:48</div>
</div>
<div class="item-subtitle">New messages from John Doe</div>
<div class="item-text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sagittis tellus ut turpis
condimentum, ut dignissim lacus tincidunt. Cras dolor metus, ultrices condimentum sodales sit amet,
pharetra sodales eros. Phasellus vel felis tellus. Mauris rutrum ligula nec dapibus feugiat. In vel
dui laoreet, commodo augue id, pulvinar lacus.
</div>
</div>
</a>
</div>
<div class="swipeout-actions-left">
<a class="color-green swipeout-overswipe" @click=${reply}>Reply</a>
<a class="color-blue" @click=${forward}>Forward</a>
</div>
<div class="swipeout-actions-right">
<a @click=${more}>More</a>
<a class="color-orange" @click=${mark}>Mark</a>
<a data-confirm="Are you sure you want to delete this item?"
class="swipeout-delete swipeout-overswipe">Delete</a>
</div>
</li>
<li class="swipeout">
<div class="swipeout-content">
<a class="item-link item-content">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">John Doe (via Twitter)</div>
<div class="item-after">15:32</div>
</div>
<div class="item-subtitle">John Doe (@_johndoe) mentioned you on Twitter!</div>
<div class="item-text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sagittis tellus ut turpis
condimentum, ut dignissim lacus tincidunt. Cras dolor metus, ultrices condimentum sodales sit amet,
pharetra sodales eros. Phasellus vel felis tellus. Mauris rutrum ligula nec dapibus feugiat. In vel
dui laoreet, commodo augue id, pulvinar lacus.
</div>
</div>
</a>
</div>
<div class="swipeout-actions-left">
<a class="color-green swipeout-overswipe" @click=${reply}>Reply</a>
<a class="color-blue" @click=${forward}>Forward</a>
</div>
<div class="swipeout-actions-right">
<a @click=${more}>More</a>
<a class="color-orange" @click=${mark}>Mark</a>
<a data-confirm="Are you sure you want to delete this item?"
class="swipeout-delete swipeout-overswipe">Delete</a>
</div>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default (props, { $f7, $onMounted, $onBeforeUnmount }) => {
let actions;
const more = () => {
actions.open();
}
const mark = () => {
$f7.dialog.alert('Mark');
}
const reply = () => {
$f7.dialog.alert('Reply');
}
const forward = () => {
$f7.dialog.alert('Forward');
}
const onDeleted = () => {
$f7.dialog.alert('Thanks, item removed!');
}
$onBeforeUnmount(() => {
actions.destroy();
})
$onMounted(() => {
actions = $f7.actions.create({
buttons: [
[
{
text: 'Here comes some optional description or warning for actions below',
label: true,
},
{
text: 'Action 1',
},
{
text: 'Action 2',
},
],
[
{
text: 'Cancel',
strong: true,
}
]
],
})
})
return $render;
}
</script>