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>
Where:
swipeout-content
- 列表元素的包装器。此容器在滑动列表项时会移动swipeout-actions-left
- 包含左侧 swipeout 操作按钮/链接的容器swipeout-actions-right
- 包含右侧 swipeout 操作按钮/链接的容器swipeout-close
- 在点击此链接时将关闭 swipeout 元件的附加类swipeout-delete
- 在点击此链接时将删除 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 操作按钮添加swipeout-delete
类:
<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>
超滑
Swipeouts 还支持 "超滑" 操作,如果您滑动操作过多,将自动触发这些操作。在这种情况下,我们需要向所需的操作按钮添加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 操作中的第一个按钮。
通过超滑,脚本将自动在超滑按钮上触发 "点击" 事件,因此您需要为此按钮添加适当的事件监听器
超滑按钮在超滑期间将具有额外的
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 App 方法
Swipeouts 还具有丰富的 JavaScript API,允许您控制 swipeout 元素。让我们看一下适当 App 的方法:
app.swipeout.open(el, 侧, 回调)- 在指定的元素上显示 swipeout 操作
- el - HTMLElement或字符串(使用 CSS 选择器) 列表 (<li>) 元素,带有 "swipeout" 类。必需
- 侧 - 字符串(可以是 "left" 或 "right") 要打开的 swipeout 操作。如果项目具有左右 swipeout 操作,则应指定。可选
- 回调 - 函数- 在 swipeout 元素完成打开动画后执行回调函数
app.swipeout.close(el, 回调)- 在指定的元素上关闭 swipeout 操作
- el - HTMLElement或字符串(使用 CSS 选择器) 列表 (<li>) 元素,带有 "swipeout" 类。必需
- 回调 - 函数- 在 swipeout 元素完成关闭动画后执行回调函数
app.swipeout.delete(el, 回调)- 删除指定的 swipeout 元素
- el - HTMLElement或字符串(使用 CSS 选择器) 列表 (<li>) 元素,带有 "swipeout" 类。必需
- 回调 - 函数- 在 swipeout 元素完成删除动画之前,在它从 DOM 中移除之前执行回调函数
app.swipeout.el- 属性。当前打开的 swipeout HTMLElement。或undefined
如果没有打开的 swipeout 元素
Swipeout App 参数
可以通过在swipeout
属性下传递 swipeout 相关参数来在应用初始化时配置全局 swipeout 行为。
参数 | 类型 | 默认 | 描述 |
---|---|---|---|
noFollow | 布尔值 | false | 用于在旧/慢设备上潜在更好性能的回退选项。如果您启用它,则 swipeout 项在触摸时不会跟随您的手指,它将在滑动左右时自动打开/关闭。 |
removeElements | 布尔值 | true | 当禁用时,框架不会在 "swipeout-delete" 点击时从 DOM 中移除 swipeout 元素。如果您使用其他库(如 Vue 或 React)来管理(删除)swipeout 项,则启用它很有用 |
removeElementsWithTimeout | 布尔值 | false | 当启用时,框架将在 "swipeout-delete" 点击后在指定延迟后从 DOM 中移除 swipeout 元素 |
removeElementsTimeout | 数字 | 0 | 如果removeElementsWithTimeout is enabled. |
overswipeRatio | 数字 | 1.2 | 定义了滑动多少/多硬以触发超滑(默认为 1.2) |
要更改这些参数,我们需要在应用初始化时在swipeout
属性下传递它们,例如:
var app = new Framework7({
swipeout: {
noFollow: true,
removeElements: false
}
});
Swipeout 事件
Swipeout 将触发以下 DOM 事件和应用实例事件:
DOM 事件
事件 | Target | 描述 |
---|---|---|
swipeout | Swipeout 元素<li class="swipeout"> | 滑动 swipeout 元素时将触发事件。event.detail contains current opening progress percentage |
swipeout:open | Swipeout 元素<li class="swipeout"> | 当滑动删除元素开始其打开动画时将触发事件 |
swipeout:opened | Swipeout 元素<li class="swipeout"> | 当滑动删除元素完成其打开动画后触发事件 |
swipeout:close | Swipeout 元素<li class="swipeout"> | 当滑动删除元素开始其关闭动画时将触发事件 |
swipeout:closed | Swipeout 元素<li class="swipeout"> | 当滑动删除元素完成其删除动画后触发事件 |
swipeout:delete | Swipeout 元素<li class="swipeout"> | 当滑动删除元素开始其删除动画后触发事件 |
swipeout:deleted | Swipeout 元素<li class="swipeout"> | 当滑动删除元素完成其删除动画后触发事件,就在它将被从 DOM 中移除之前 |
swipeout:overswipeenter | Swipeout 元素<li class="swipeout"> | 当启用溢出时将触发事件 |
swipeout:overswipeexit | Swipeout 元素<li class="swipeout"> | 当禁用溢出时将触发事件 |
应用实例事件
Swipeout 实例在应用实例上发出事件。
事件 | Target | 参数 | 描述 |
---|---|---|---|
swipeout | app | 进度 | 当您移动 swipeout 元素时将触发事件 |
swipeoutOpen | app | swipeoutEl | 当滑动删除元素开始其打开动画时将触发事件 |
swipeoutOpened | app | swipeoutEl | 当滑动删除元素完成其打开动画后触发事件 |
swipeoutClose | app | swipeoutEl | 当滑动删除元素开始其关闭动画时将触发事件 |
swipeoutClosed | app | swipeoutEl | 当滑动删除元素完成其删除动画后触发事件 |
swipeoutDelete | app | swipeoutEl | 当滑动删除元素开始其删除动画后触发事件 |
swipeoutDeleted | app | swipeoutEl | 当滑动删除元素完成其删除动画后触发事件,就在它将被从 DOM 中移除之前 |
swipeoutOverswipeEnter | app | swipeoutEl | 当启用溢出时将触发事件 |
swipeoutOverswipeExit | app | swipeoutEl | 当禁用溢出时将触发事件 |
CSS 变量
以下是相关CSS 变量(CSS 自定义属性) 的列表。
: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;
}
示例
<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>