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-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-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アクションの最初のボタンでのみ使用できます。
オーバーズワイプを使用すると、スクリプトはオーバーズワイプボタンの「クリック」イベントを自動的にトリガーするため、このボタンに適切なイベントリスナーを追加する必要があります。
オーバーズワイプボタンは、オーバーズワイプ中に追加の
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には、swipeout要素を制御できる豊富なJavaScript APIもあります。適切なアプリのメソッドを見てみましょう。
app.swipeout.open(el, side, callback) - 指定された要素でswipeoutアクションを表示します。
- el - HTMLElementまたは文字列(CSSセレクター付き)"swipeout"クラスを持つリスト(<li>)要素。必須です。
- side - 文字列(「left」または「right」)。開くswipeoutアクション。アイテムに左右両方のswipeoutアクションがある場合は指定する必要があります。オプションです。
- callback - 関数 - swipeout要素が開くアニメーションが完了した後、コールバック関数が実行されます。
app.swipeout.close(el, callback) - 指定された要素でswipeoutアクションを閉じます。
- el - HTMLElementまたは文字列(CSSセレクター付き)"swipeout"クラスを持つリスト(<li>)要素。必須です。
- callback - 関数 - swipeout要素が閉じるアニメーションが完了した後、コールバック関数が実行されます。
app.swipeout.delete(el, callback) - 指定されたswipeout要素を削除します。
- el - HTMLElementまたは文字列(CSSセレクター付き)"swipeout"クラスを持つリスト(<li>)要素。必須です。
- callback - 関数 - swipeout要素が削除アニメーションを完了した後、DOMから削除される直前にコールバック関数が実行されます。
app.swipeout.el - プロパティ。現在開いているswipeout HTMLElement。開いているswipeout要素がない場合はundefined
。
Swipeout アプリパラメーター
swipeout
プロパティの下にあるswipeout関連のパラメーターを渡すことで、アプリの初期化時にグローバルなswipeout動作を構成できます。
パラメーター | タイプ | デフォルト | 説明 |
---|---|---|---|
noFollow | ブール値 | false | 古い/遅いデバイスでのパフォーマンス向上のためのフォールバックオプション。有効にすると、swipeoutアイテムはタッチ中に指に従わず、左/右にスワイプすると自動的に開閉されます。 |
removeElements | ブール値 | ブール値 | true |
無効にすると、フレームワークは「swipeout-delete」クリック時にDOMからswipeout要素を削除しません。VueやReactなどの別のライブラリを使用してswipeoutアイテムを管理(削除)する場合に有効です。 | ブール値 | false | removeElementsWithTimeout |
ブール値 | false | 0 | 有効にすると、指定された遅延後に「swipeout-delete」クリック時にフレームワークがDOMからswipeout要素を削除します。 |
removeElementsTimeout | false | 1.2 | 数値 |
removeElementsWithTimeout
が有効な場合、swipeoutアイテムを削除する遅延(ミリ秒)。
var app = new Framework7({
swipeout: {
noFollow: true,
removeElements: false
}
});
overswipeRatio
数値
1.2
オーバーズワイプをトリガーするために必要なスワイプの量/強さを定義します(デフォルトは1.2)。 | これらのパラメーターを変更するには、アプリの初期化時にswipeout プロパティの下に渡す必要があります。例: | 説明 |
---|---|---|
Swipeout イベント | Swipeoutは、次のDOMイベントとアプリインスタンスのイベントを発生させます。 | DOM イベント |
イベント | Swipeoutは、次のDOMイベントとアプリインスタンスのイベントを発生させます。 | ターゲット |
swipeout | Swipeoutは、次のDOMイベントとアプリインスタンスのイベントを発生させます。 | Swipeout 要素<li class="swipeout"> |
swipeout要素を移動中にトリガーされます。event.detail には、現在の開始進行状況のパーセンテージが含まれています。 | Swipeoutは、次のDOMイベントとアプリインスタンスのイベントを発生させます。 | swipeout:open |
swipeout要素が開くアニメーションを開始したときにトリガーされます。 | Swipeoutは、次のDOMイベントとアプリインスタンスのイベントを発生させます。 | swipeout:opened |
swipeout要素が開くアニメーションが完了したときにトリガーされます。 | Swipeoutは、次のDOMイベントとアプリインスタンスのイベントを発生させます。 | swipeout:close |
swipeout要素が閉じるアニメーションを開始したときにトリガーされます。 | Swipeoutは、次のDOMイベントとアプリインスタンスのイベントを発生させます。 | swipeout:closed |
swipeout要素が閉じるアニメーションが完了したときにトリガーされます。 | Swipeoutは、次のDOMイベントとアプリインスタンスのイベントを発生させます。 | swipeout:delete |
swipeout要素が削除アニメーションを開始したときにトリガーされます。 | Swipeoutは、次のDOMイベントとアプリインスタンスのイベントを発生させます。 | swipeout:deleted |
swipeout要素が削除アニメーションを完了した後、DOMから削除される直前にトリガーされます。
swipeout:overswipeenter
オーバーズワイプをトリガーするために必要なスワイプの量/強さを定義します(デフォルトは1.2)。 | これらのパラメーターを変更するには、アプリの初期化時にswipeout プロパティの下に渡す必要があります。例: | オーバーズワイプが有効になったときにトリガーされます。 | 説明 |
---|---|---|---|
Swipeout イベント | swipeout:overswipeexit | オーバーズワイプが無効になったときにトリガーされます。 | アプリインスタンスイベント |
Swipeoutインスタンスは、アプリインスタンスでイベントを発生させます。 | swipeout:overswipeexit | 引数 | ターゲット |
app | swipeout:overswipeexit | 引数 | Swipeout 要素<li class="swipeout"> |
progress | swipeout:overswipeexit | 引数 | swipeout:open |
swipeout要素を移動中にトリガーされます。 | swipeout:overswipeexit | 引数 | swipeout:opened |
swipeoutOpen | swipeout:overswipeexit | 引数 | swipeout:close |
swipeoutEl | swipeout:overswipeexit | 引数 | swipeout:closed |
swipeoutOpened | swipeout:overswipeexit | 引数 | swipeout:delete |
swipeoutClose | swipeout:overswipeexit | 引数 | swipeout:deleted |
CSS変数
swipeoutClosed
: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;
}
swipeoutDelete
<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>