滑動刪除(可滑動清單)

滑動刪除是 清單檢視 的延伸,讓您可以在清單元素上滑動,以顯示隱藏功能表,其中包含可用動作,例如滑動刪除。

滑動刪除配置

讓我們看看清單檢視中滑動刪除元素的配置結構

<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-contentswipeout-actions-left/right 應為 <li> 的直接子項目

如果您只有「項目內容」,您可以透過將「項目內容」類別新增至「滑動刪除內容」來簡化配置

<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 類別新增至滑動刪除動作按鈕即可

<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-confirmdata-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-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-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 也有豐富的 JavaScript API,讓你可以控制 Swipeout 元素。讓我們來看看適用的 App 方法

app.swipeout.open(el, side, callback) - 在指定的元素上顯示 Swipeout 動作

  • el - HTMLElementstring (使用 CSS 選擇器) 的清單 (<li>) 元素,帶有「swipeout」類別。必填
  • side - string (可以是「left」或「right」) 要開啟的 Swipeout 動作。如果項目同時有左右 Swipeout 動作,則應指定。選填
  • callback - function - 在 Swipeout 元素完成其開啟動畫後,將執行 callback 函式

app.swipeout.close(el, callback) - 在指定的元素上關閉 Swipeout 動作

  • el - HTMLElementstring (使用 CSS 選擇器) 的清單 (<li>) 元素,帶有「swipeout」類別。必填
  • callback - function - 在 Swipeout 元素完成其關閉動畫後,將執行 callback 函式

app.swipeout.delete(el, callback) - 刪除指定的 Swipeout 元素

  • el - HTMLElementstring (使用 CSS 選擇器) 的清單 (<li>) 元素,帶有「swipeout」類別。必填
  • callback - function - 在 Swipeout 元素完成其刪除動畫後,將執行 callback 函式,緊接著它將從 DOM 中移除

app.swipeout.el - 屬性。目前開啟的 Swipeout HTMLElement。或者如果沒有開啟的 Swipeout 元素,則為 undefined

Swipeout App 參數

可以在 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,延遲以毫秒為單位移除 swipeout 項目。
overswipeRatio數字1.2定義觸發 overswipe 所需的滑動量/強度(預設為 1.2)

若要變更這些參數,我們需要在 swipeout 屬性下於應用程式初始化時傳遞它們,例如

var app = new Framework7({
  swipeout: {
    noFollow: true,
    removeElements: false
  }
});

Swipeout 事件

Swipeout 將觸發應用程式執行個體上的下列 DOM 事件和事件

DOM 事件

事件目標說明
swipeoutSwipeout 元素<li class="swipeout">當您移動 swipeout 元素時,將觸發事件。event.detail 包含目前的開啟進度百分比
swipeout:openSwipeout 元素<li class="swipeout">當 swipeout 元素開始其開啟動畫時,將觸發事件
swipeout:openedSwipeout 元素<li class="swipeout">當 swipeout 元素完成其開啟動畫後,將觸發事件
swipeout:closeSwipeout 元素<li class="swipeout">當 swipeout 元素開始其關閉動畫時,將觸發事件
swipeout:closedSwipeout 元素<li class="swipeout">當 swipeout 元素完成其關閉動畫後,將觸發事件
swipeout:deleteSwipeout 元素<li class="swipeout">當 swipeout 元素開始其刪除動畫後,將觸發事件
swipeout:deletedSwipeout 元素<li class="swipeout">當 swipeout 元素完成其刪除動畫後,將觸發事件,緊接在從 DOM 中移除之前
swipeout:overswipeenterSwipeout 元素<li class="swipeout">當啟用 overswipe 時,將觸發事件
swipeout:overswipeexitSwipeout 元素<li class="swipeout">當停用 overswipe 時,將觸發事件

應用程式執行個體事件

Swipeout 執行個體在應用程式執行個體上發出事件。

事件目標引數說明
swipeoutapp進度當您移動 swipeout 元素時,將觸發事件
swipeoutOpenappswipeoutEl當 swipeout 元素開始其開啟動畫時,將觸發事件
swipeoutOpenedappswipeoutEl當 swipeout 元素完成其開啟動畫後,將觸發事件
swipeoutCloseappswipeoutEl當 swipeout 元素開始其關閉動畫時,將觸發事件
swipeoutClosedappswipeoutEl當 swipeout 元素完成其關閉動畫後,將觸發事件
swipeoutDeleteappswipeoutEl當 swipeout 元素開始其刪除動畫後,將觸發事件
swipeoutDeletedappswipeoutEl當 swipeout 元素完成其刪除動畫後,將觸發事件,緊接在從 DOM 中移除之前
swipeoutOverswipeEnterappswipeoutEl當啟用 overswipe 時,將觸發事件
swipeoutOverswipeExitappswipeoutEl當停用 overswipe 時,將觸發事件

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

範例

swipeout.html
<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>