面板/側邊面板

面板配置

讓我們看看如何將側面板新增到我們的應用程式。我們可以將最多 2 個面板包含到我們的應用程式中,一個在左側,另一個在右側。我們應該在應用程式根元素(或在沒有使用根元素的情況下為 <body>)的開頭處新增面板的 HTML

<body>
  <!-- App root element -->
  <div id="app">
    <!-- Left panel -->
    <div class="panel panel-left">
        ... panel content goes here ...
    </div>

    <!-- Right panel -->
    <div class="panel panel-right">
        ... panel content goes here ...
    </div>

    ...
  </div>
</body>

新增面板後,我們需要為每個面板選擇開啟效果。以下是可以選擇的效果之一

如果您想使用「顯示」效果,您應該在面板中新增額外的 panel-reveal 類別,在覆蓋效果中新增 panel-cover,或在推動效果中新增 panel-push

<body>
  <!-- App root element -->
  <div id="app">
    <!-- Left panel, let it be with reveal effect -->
    <div class="panel panel-left panel-reveal">
        ... panel content goes here ...
    </div>

    <!-- Right panel, with cover effect -->
    <div class="panel panel-right panel-cover">
        ... panel content goes here ...
    </div>

    ...
  </div>
</body>

每個面板都可以調整大小。要使面板可以調整大小,我們只需要在面板元素中新增 panel-resizable 類別

<body>
  <!-- App root element -->
  <div id="app">
    <!-- Make left panel resizable -->
    <div class="panel panel-left panel-resizable">
        ... panel content goes here ...
    </div>

    <!-- Make right panel resizable -->
    <div class="panel panel-right panel-resizable">
        ... panel content goes here ...
    </div>
    ...
  </div>
</body>

面板應用程式方法

讓我們看看相關的應用程式方法來使用面板

app.panel.create(parameters)- 建立面板執行個體

  • parameters - 物件。具有面板參數的物件

方法傳回建立的面板執行個體

app.panel.destroy(el)- 銷毀面板執行個體

  • el - HTMLElement字串(具有 CSS 選擇器)或 物件。要銷毀的面板元素或面板執行個體。

app.panel.get(el)- 透過 HTML 元素取得面板執行個體

  • el - HTMLElement字串(具有 CSS 選擇器)。面板元素。

方法傳回面板執行個體

app.panel.open(panel, animate)- 開啟面板

  • panel - HTMLElement字串(具有 CSS 選擇器)要開啟的面板元素
  • animate - 布林值。是否應該使用動畫開啟。選用,預設為 true

app.panel.close(panel, animate)- 關閉面板

  • panel - HTMLElement字串(具有 CSS 選擇器)要關閉的面板元素
  • animate - 布林值。是否應以動畫方式關閉。選用,預設為 true

app.panel.toggle(panel, animate)- 切換面板

  • panel - HTMLElement字串 (搭配 CSS 選擇器) 的面板元素,用於切換
  • animate - 布林值。是否應以動畫方式開啟/關閉。選用,預設為 true

面板參數

如果我們使用 app.panel.create 方法手動建立面板,我們需要傳遞包含面板參數的物件

參數類型預設值說明
elHTMLElement
字串
面板元素
resizable布林值啟用可調整大小的面板。如果未傳遞,將根據 panel-resizable 類別來決定。
visibleBreakpoint數字當左側面板始終可見時,應用程式的最小寬度 (以像素為單位)
collapsedBreakpoint數字當左側面板變為部分可見 (摺疊) 時,應用程式的最小寬度 (以像素為單位)
swipe布林值false如果您想要啟用使用滑動開啟/關閉面板的功能,請啟用
swipeNoFollow布林值false在舊/慢的裝置上,可作為潛在效能提升的後備選項。如果您啟用,滑動面板在觸控移動期間不會追隨您的手指,它會在向左/向右滑動時自動開啟/關閉。
swipeActiveArea數字0從螢幕觸發面板滑動的不可見邊緣寬度 (以像素為單位)
swipeOnlyClose布林值false此參數允許使用滑動關閉 (但無法開啟) 面板。(swipe 也應啟用)
swipeThreshold數字0如果「觸控距離」小於此值 (以像素為單位),面板將不會隨著滑動而移動。
backdrop布林值true啟用面板背景 (背後的深色半透明圖層)
backdropElHTMLElement
字串
自訂背景元素的 HTML 元素或字串 CSS 選擇器
closeByBackdropClick布林值true啟用/停用透過點選面板外部來關閉面板的功能
containerElHTMLElement
字串
允許將面板安裝到自訂元素,而不是應用程式根元素
on物件

包含事件處理常式的物件。例如

var panel = app.panel.create({
  el: '.panel-left',
  on: {
    opened: function () {
      console.log('Panel opened')
    }
  }
})

例如

var panel = app.panel.create({
  el: '.panel-left',
  resizable: true,
  visibleBreakpoint: 1024,
  collapsedBreakpoint: 768,
})

請注意,所有後續參數都可以在 panel 屬性下的全域應用程式參數中使用,以設定所有面板的預設值。例如

var app = new Framework7({
  panel: {
    swipe: true,
    visibleBreakpoint: 1024,
  }
});

面板方法和屬性

在我們建立面板實例(透過呼叫 app.panel.create)或取得面板實例(透過呼叫 app.panel.get)後,我們可以使用其有用的方法和屬性

屬性
panel.app連結至全域應用程式實例
panel.side包含面板側邊的字串:leftright
panel.effect包含面板效果的字串:coverrevealfloatingpush
panel.opened布林屬性,表示是否已開啟
panel.el面板 HTML 元素
panel.$el包含面板 HTML 元素的 Dom7 實例
panel.backdropEl背景 HTML 元素
panel.$backdropEl包含背景 HTML 元素的 Dom7 實例
panel.params面板參數
panel.containerEl要將面板安裝到的元素。(預設為 app.el - 根應用程式元素)
panel.$containerEl包含要將面板安裝到的元素的 Dom7 實例。(預設為 app.el - 根應用程式元素)
方法
panel.open(animate)開啟面板。其中
  • animate - 布林值(預設為 true) - 定義是否應以動畫開啟
panel.close(animate)關閉面板。其中
  • animate - 布林值(預設為 true) - 定義是否應以動畫關閉
panel.toggle(animate)切換面板。其中
  • animate - 布林值(預設為 true) - 定義是否應以動畫關閉
panel.enableVisibleBreakpoint()啟用可見斷點
panel.disableVisibleBreakpoint()停用可見斷點
panel.toggleVisibleBreakpoint()切換可見斷點
panel.enableCollapsedBreakpoint()啟用收合斷點
panel.disableCollapsedBreakpoint()停用收合斷點
panel.toggleCollapsedBreakpoint()切換收合斷點
panel.enableResizable()啟用可調整大小的面板
panel.disableResizable()停用可調整大小的面板
panel.enableSwipe()啟用可滑動的面板
panel.disableSwipe()停用可滑動的面板
panel.destroy()銷毀面板實例
panel.on(event, handler)新增事件處理常式
panel.once(event, handler)新增事件處理常式,該常式會在觸發後移除
panel.off(event, handler)移除事件處理常式
panel.off(event)移除指定事件的所有處理常式
panel.emit(event, ...args)在實例上觸發事件

面板事件

面板將在面板元素上觸發以下 DOM 事件,以及在應用程式和面板實例上觸發事件

DOM 事件

事件目標說明
panel:open面板元素<div class="panel">當面板開始其開啟動畫時,將觸發事件
panel:opened面板元素<div class="panel">當面板完成其開啟動畫後,將觸發事件
panel:close面板元素<div class="panel">當面板開始其關閉動畫時,將觸發事件
panel:closed面板元素<div class="panel">當面板完成其關閉動畫後,將觸發事件
panel:backdrop-click面板覆蓋元素<div class="panel-backdrop">當按一下面板覆蓋時,將觸發事件
panel:swipeopen面板元素<div class="panel">在使用滑動開啟它的最開始時,將觸發事件
panel:swipe面板元素<div class="panel">在觸控滑動動作期間,將觸發觸控面板事件
panel:collapsedbreakpoint面板元素<div class="panel">當應用程式寬度與其 collapsedBreakpoint 相符時,它變為可見/隱藏時,將觸發事件
panel:breakpoint面板元素<div class="panel">當應用程式寬度與其 visibleBreakpoint 相符時,它變為可見/隱藏時,將觸發事件
panel:resize面板元素<div class="panel">在可調整大小的面板調整大小時,將觸發事件
panel:beforedestroy面板元素<div class="panel">在面板實例即將被銷毀之前,將觸發事件

應用程式和面板實例事件

面板實例在自身實例和應用程式實例上發出事件。應用程式實例事件具有相同的名稱,前面加上 panel

事件目標參數說明
openpanel(panel)當面板開始其開啟動畫時,將觸發事件。作為參數,事件處理常式接收面板實例
panelOpenapp(panel)
openedpanel(panel)當面板完成其開啟動畫時,將觸發事件。作為參數,事件處理常式接收面板實例
panelOpenedapp(panel)
closepanel(panel)當面板開始其關閉動畫時,將觸發事件。作為參數,事件處理常式接收面板實例
panelCloseapp(panel)
closedpanel(panel)當面板完成其關閉動畫時,將觸發事件。作為參數,事件處理常式接收面板實例
panelClosedapp(panel)
backdropClickpanel(panel)當按一下面板覆蓋時,將觸發事件。作為參數,事件處理常式接收面板實例
panelBackdropClickapp(panel)
swipeOpenpanel(panel)在使用滑動開啟它的最開始時,將觸發事件。作為參數,事件處理常式接收面板實例
panelSwipeOpenapp(panel)
swipepanel(面板、進度)觸控滑動動作期間,滑動面板的事件將被觸發。事件處理常式接收面板實例和開啟進度(從 0 到 1)作為參數
panelSwipeapp(面板、進度)
collapsedBreakpointpanel(panel)當應用程式寬度符合其 collapsedBreakpoint 時,事件將在它變為可見/隱藏時觸發。事件處理常式接收面板實例作為參數
panelCollapsedBreakpointapp(panel)
中斷點panel(panel)當應用程式寬度符合其 visibleBreakpoint 時,事件將在它變為可見/隱藏時觸發。事件處理常式接收面板實例作為參數
panelBreakpointapp(panel)
調整大小panel(面板、新面板寬度)在可調整大小的面板調整大小時,將觸發事件
panelResizeapp(panel)
beforeDestroypanel(panel)在面板實例即將被銷毀之前,將觸發事件
panelBeforeDestroyapp(panel)

面板自動初始化

如果您不需要使用面板 API,而且您的面板在初始化時位於應用程式內部,或位於頁面內部並在頁面初始化時顯示在 DOM 中,則只需新增額外的 panel-init 類別即可自動初始化。

<!-- Add panel-init class -->
<div class="panel panel-left panel-cover panel-init">
  ...
</div>

在這種情況下,如果您需要存取已建立的面板實例,可以使用 app.panel.get 應用程式方法

var panel = app.panel.get('.panel-left');

if (panel.opened) {
  // do something
}

使用自動初始化時,您可能需要傳遞額外的參數。這可以使用面板元素上的 data- 屬性來完成。

<!-- parameters set via data- attributes -->
<div
  class="panel panel-left panel-reveal panel-init"
  data-collapsed-breakpoint="768"
  data-visible-breakpoint="1024"
  data-swipe="true"
>
  ...
</div>

在 camelCase 中使用的參數,例如 visibleBreakpoint,在 data 屬性中應使用 kebab-case,例如 data-visible-breakpoint

可以使用連結上的特殊類別和資料屬性來開啟和關閉所需的 painel(如果您在 DOM 中有它們)

  • 若要開啟面板,我們需要將 panel-open 類別新增到任何 HTML 元素(建議連結)

  • 若要關閉面板,我們需要將 panel-close 類別新增到任何 HTML 元素(建議連結)

  • 若要切換面板,我們需要將 panel-toggle 類別新增到任何 HTML 元素(建議連結)

  • 如果您想指定應開啟/關閉哪個面板,則可以透過此 HTML 元素上的額外 data-panel=".panel-left" 屬性來完成。如果 DOM 中只有一側有此類面板,則此屬性也可以只接收 leftright 值。

根據上述說明

<body>
  <div id="app">
    <!-- Left Panel with Reveal effect -->
    <div class="panel panel-left panel-reveal panel-init">
      <div class="block">
        ...
        <!-- Clicking on link with "panel-close" class will close panel -->
        <p><a href="#" class="panel-close">Close me</a></p>
        <!-- Click on link with "panel-open" and data-panel=".panel-right" attribute will open Right panel -->
        <p><a href="#" data-panel=".panel-right" class="panel-open">Open Right Panel</a></p>
      </div>
    </div>

    <!-- Right Panel with Cover effect -->
    <div class="panel panel-right panel-cover panel-init">
      <div class="block">
        ...
        <!-- Click on link with "panel-close" class will close panel -->
        <p><a href="#" class="panel-close">Close me</a></p>
        <!-- Click on link with "panel-open" and data-panel=".panel-left" attribute will open Left panel -->
        <p><a href="#" data-panel=".panel-left" class="panel-open">Open Left Panel</a></p>
      </div>
    </div>

    ...
    <div class="page-content">
      <div class="block">
        <!-- Click on link with "panel-open" and data-panel=".panel-left" attribute will open Left panel -->
        <p><a href="#" data-panel=".panel-left" class="panel-open">Open Left Panel</a></p>
        <!-- Click on link with "panel-open" and data-panel=".panel-right" attribute will open Right panel -->
        <p><a href="#" data-panel=".panel-right" class="panel-open">Open Right Panel</a></p>
      </div>
    </div>
  </div>
  ...
</body>

可路由面板

面板也可以與可路由模式和頁面具有相同的功能

routes = [
  ...
  // Creates Panel from passed HTML string
  {
    path: '/left-panel/',
    panel: {
      content: `
        <div class="panel panel-left panel-cover">
          <div class="view">
            <div class="page">
              ...
            </div>
          </div>
        </div>
      `
    }
  },
  // Load Panel from file via Ajax
  {
    path: '/right-panel-ajax/',
    panel: {
      url: './right-panel.html',
      /* right-panel.html contains:
      <div class="panel panel-right panel-reveal">
        <div class="view">
          <div class="page">
            ...
          </div>
        </div>
      </div>
      */
    },
  },
  // Load Panel from component file
  {
    path: '/panel-component/',
    panel: {
      componentUrl: './panel-component.html',
      /* panel-component.html contains:
      <template>
        <div class="panel panel-left panel-cover">
          <div class="view">
            <div class="page">
              ...
            </div>
          </div>
        </div>
      </template>
      <style>...</style>
      <script>...</script>
      */
    },
  },
]

根據上述範例

巢狀面板

除了主要應用程式面板之外,也可以有巢狀面板,例如在頁面內部。要建立巢狀面板,我們需要指定其 containerEl 參數,指向父容器(例如頁面元素),並將其置於 page-content 元素之前。

<div class="page" id="panel-page">
  <div class="navbar">
    <!-- ... -->
  </div>

  <!-- Nested panel has parent page specified in containerEl parameter -->
  <div class="panel panel-left panel-cover panel-init dark" id="panel-nested" data-container-el="#panel-page">
    <div class="page">
      <!-- ... -->
    </div>
  </div>

  <!-- Rest of the page -->
  <div class="page-content">
    <!-- ... -->
  </div>
</div>

CSS 變數

以下是相關 CSS 變數(CSS 自訂屬性)清單。

請注意,註解的變數預設未指定,其值為在此情況下的備用值。

:root {
  --f7-panel-width: 260px;
  --f7-panel-backdrop-bg-color: rgba(0, 0, 0, 0.3);
  /*
  --f7-panel-left-width: var(--f7-panel-width);
  --f7-panel-right-width: var(--f7-panel-width);
  --f7-panel-left-collapsed-width: var(--f7-panel-collapsed-width);
  --f7-panel-right-collapsed-width: var(--f7-panel-collapsed-width);
  */
  --f7-panel-bg-color: #fff;
}
:root .dark,
:root.dark {
  --f7-panel-bg-color: #000;
}
.ios {
  --f7-panel-collapsed-width: 58px;
  --f7-panel-transition-duration: 400ms;
  --f7-panel-transition-timing-function: initial;
}
.md {
  --f7-panel-collapsed-width: 60px;
  --f7-panel-transition-duration: 400ms;
  --f7-panel-transition-timing-function: cubic-bezier(0, 0.8, 0.34, 1);
}

範例

panel.html
<div class="page" id="panel-page">
  <div class="navbar">
    <div class="navbar-bg"></div>
    <div class="navbar-inner sliding">
      <div class="title">Panel / Side panels</div>
    </div>
  </div>
  <div class="panel panel-left panel-cover panel-init" id="panel-nested" data-container-el="#panel-page">
    <div class="page">
      <div class="page-content">
        <div class="block block-strong-ios block-outline-ios">
          <p>This is page-nested Panel.</p>
          <p><a class="panel-close">Close me</a></p>
        </div>
      </div>
    </div>
  </div>

  <div class="page-content">
    <div class="block block-strong-ios block-outline-ios">
      <p>Framework7 comes with 2 panels (on left and on right), both are optional.
        You can put absolutely anything inside: data lists, forms, custom content, and even other isolated app view
        (like in right panel now) with its own dynamic navbar.</p>
    </div>
    <div class="block block-strong-ios block-outline-ios">
      <p class="grid grid-cols-2 grid-gap">
        <a class="button button-raised button-fill panel-open">Open left panel</a>
        <a class="button button-raised button-fill panel-open" data-panel="right">Open right panel</a>
      </p>
      <p>
        <a class="button button-raised button-fill panel-open" data-panel="#panel-nested">Open nested panel</a>
      </p>
    </div>
  </div>
</div>