スポンサー
Support Framework7

パネル / サイドパネル

    パネルのレイアウト

    アプリにサイドパネルを追加する方法を見てみましょう。アプリには最大2つのパネルを追加することができ、1つは左側に、もう1つは右側に配置することができます。パネルのHTMLは、アプリのルート要素(ルート要素がない場合は、<body>)の先頭に追加します。

    <body>
      <!-- アプリのルート要素 -->
      <div id="app">
        <!-- 左パネル -->
        <div class="panel panel-left">
            ... panel content goes here ...
        </div>
    
        <!-- 右パネル -->
        <div class="panel panel-right">
            ... panel content goes here ...
        </div>
    
        ...
      </div>
    </body>

    パネルを追加した後は、各パネルのオープニング効果を選択する必要があります。以下のようなものが考えられます。

    • "reveal" - パネルがアプリのコンテンツ全体に移動します。
    • "cover" - パネルがアプリのコンテンツをオーバーレイするとき。
    • 「push」 - パネルとアプリのコンテンツの両方が一緒に移動する場合。

    Reveal "効果を使用したい場合は、Panel に追加の panel-reveal クラスを、カバー効果の場合は panel-cover を、プッシュ効果の場合は panel-push を追加する必要があります。

    <body>
      <!-- アプリのルート要素 -->
      <div id="app">
        <!-- 左パネルには、明らかにする効果があります。 -->
        <div class="panel panel-left panel-reveal">
            ... panel content goes here ...
        </div>
    
        <!-- 右パネル、カバー効果あり -->
        <div class="panel panel-right panel-cover">
            ... panel content goes here ...
        </div>
    
        ...
      </div>
    </body>

    各パネルはサイズ変更が可能です。Panelをリサイズ可能にするには、Panel要素にpanel-resizableクラスを追加する必要があります。

    <body>
      <!-- アプリのルート要素 -->
      <div id="app">
        <!-- 左パネルをリサイズ可能にする -->
        <div class="panel panel-left panel-resizable">
            ... panel content goes here ...
        </div>
    
        <!-- 右パネルをリサイズ可能にする -->
        <div class="panel panel-right panel-resizable">
            ... panel content goes here ...
        </div>
        ...
      </div>
    </body>
    

    パネルアプリのメソッド

    Panel を扱う App の関連メソッドを見てみましょう。

    app.panel.create(parameters)- パネルのインスタンスを作成する

    • parameters - object. パネルのパラメータを持つオブジェクト

    作成されたPanelのインスタンスを返すメソッド

    app.panel.destroy(el)- Panelインスタンスの破棄

    • el - HTMLElementまたはstring(CSSセレクタ付き)またはobject。破壊するPanel要素またはPanelインスタンスです。

    app.panel.get(el)- HTML要素によるPanelインスタンスの取得

    • el - HTMLElement または string (CSS セレクタを使用). Panelの要素です。

    メソッドは、Panel のインスタンスを返します。

    app.panel.open(panel, animate)- オープンパネル

    • panel - 開くパネル要素の HTMLElement または string (with CSS Selector) です。
    • animate - boolean。アニメーションで開くかどうかを指定します。任意ですが、デフォルトでは true です。

    app.panel.close(panel, animate)- パネルを閉じる

    • panel - 閉じるパネル要素の HTMLElement または string (with CSS Selector) を指定します。
    • animate - boolean。アニメーションで閉じるかどうかを指定します。任意ですが、デフォルトでは true です。

    app.panel.toggle(panel, animate)- パネルのトグル

    • panel - HTMLElementまたはstring (CSS Selectorを使用した場合)のパネル要素をトグルします。
    • animate - boolean。アニメーションで開閉するかどうかを指定します。任意ですが、デフォルトでは true です。

    パネルのパラメータ

    app.panel.create`メソッドを使って手動でパネルを作成する場合、パネルのパラメータをオブジェクトに渡す必要があります。

    ParameterTypeDefaultDescription
    elHTMLElement
    string
    パネル要素
    resizablebooleanサイズ変更可能なパネルを有効にします。渡していない場合は、panel-resizableクラスに基づいて決定されます。
    visibleBreakpointnumber左パネルが常に表示されるようになったときの、アプリの最小幅(px)です。
    collapsedBreakpointnumber左パネルが部分的に表示される(折りたたまれる)場合の最小アプリ幅(px単位
    swipebooleanfalseスワイプでパネルを開閉する機能を有効にしたい場合は、Enableを選択します。
    swipeNoFollowbooleanfalse古いデバイスや遅いデバイスでのパフォーマンスを向上させる可能性のあるフォールバックオプションです。このオプションを有効にすると、タッチ操作時にスワイプパネルが指に追従せず、左右のスワイプで自動的に開閉されるようになります。
    swipeActiveAreanumber0パネルのスワイプを誘発するスクリーンからの見えないエッジの幅(px)
    swipeOnlyClosebooleanfalseこのパラメータは、スワイプでパネルを閉じる(開かない)ことができます。(swipe も有効にしてください)
    swipeThresholdnumber0touch distance" がこの値 (px) よりも小さい場合、パネルはスワイプでは動きません。
    backdropbooleantrueパネルの背景を有効にします (背後にある暗い半透明のレイヤー)
    backdropElHTMLElement
    string
    カスタム背景要素の HTML 要素または文字列 CSS セレクタ
    closeByBackdropClickbooleantrueパネルの外側をクリックしてパネルを閉じる機能の有効化/無効化
    containerElHTMLElement
    string
    パネルをアプリのルート要素ではなく、カスタム要素にマウントすることを可能にする。
    onobject

    イベントハンドラーを持つオブジェクト。例えば、以下のようになります。

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

    パネルのメソッドとプロパティ

    Panel のインスタンスを作成した後(app.panel.create を呼び出し)、または Panel のインスタンスを取得した後(app.panel.get を呼び出し)、その便利なメソッドとプロパティを使用できます。

    Properties
    panel.appグローバルアプリのインスタンスへのリンク
    panel.sideパネルの側面を表す文字列: left または right
    panel.effectパネルの効果を表す文字列: cover, reveal, push のいずれか。
    panel.openedパネルが開かれているかどうかを示すブール値のプロパティ
    panel.elパネルのHTML要素
    panel.$elパネル HTML 要素を持つ Dom7 インスタンス
    panel.backdropEl背景のHTML要素
    panel.$backdropEl背景のHTML要素を持つDom7インスタンス
    panel.paramsパネルパラメータ
    panel.containerElパネルをマウントする要素。(default app.el - root app element)
    panel.$containerElパネルをマウントする要素を持つ Dom7 インスタンス。(default app.el - root app element)
    Methods
    panel.open(animate)パネルを開きます。ここでは
    • animate - boolean (デフォルトでは true) - アニメーションを使って開くかどうかを定義します。
    panel.close(animate)パネルを閉じます。パネルを閉じる
    • animate - boolean (デフォルトでは true) - アニメーションで閉じるかどうかを定義します。
    panel.toggle(animate)パネルをトグルします。パネルの切り替え
    • animate - boolean (デフォルトでは 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)インスタンスでのイベント発生

    パネルイベント

    Panel は、以下の DOM イベントを Panel 要素で、イベントを app と Panel インスタンスで発生させます。

    DOM イベント

    EventTargetDescription
    panel:openPanel Element<div class="panel">イベントは、Panel がオープニングアニメーションを開始したときに発生します。
    panel:openedPanel Element<div class="panel">イベントは、Panel がオープニングアニメーションを完了した後に発生します。
    panel:closePanel Element<div class="panel">イベントは、Panel が閉じるアニメーションを開始したときに発生します。
    panel:closedPanel Element<div class="panel">パネルが閉じるアニメーションが完了すると、イベントが発生します。
    panel:backdrop-clickPanel Overlay Element<div class="panel-backdrop">イベントは、パネルのオーバーレイがクリックされたときに発生します。
    panel:swipeopenPanel Element<div class="panel">イベントはスワイプでパネルを開く最初の段階で発生します。
    panel:swipePanel Element<div class="panel">イベントはタッチ・スワイプ動作中にパネルのスワイプに対して発生します。
    panel:collapsedbreakpointPanel Element<div class="panel">アプリの幅が collapsedBreakpoint と一致したときに表示/非表示になるとイベントが発生します。
    panel:breakpointPanel Element<div class="panel">イベントはアプリの幅が visibleBreakpoint と一致したときに表示/非表示になるとトリガーされます。
    panel:resizePanel Element<div class="panel">イベントはサイズ変更可能なパネルのリサイズ時にトリガーされます。
    panel:beforedestroyPanel Element<div class="panel">イベントは Panel インスタンスが破棄される直前に発生します。

    アプリと Panel インスタンスのイベント

    Panel インスタンスは、self インスタンスと app インスタンスの両方に対してイベントを発行します。アプリのインスタンスのイベントは、同じ名前でプレフィックスが panel となっています。

    EventTargetArgumentsDescription
    openpanel(panel)イベントは、Panel がオープニングアニメーションを開始したときにトリガされます。イベントハンドラは引数として、Panel インスタンスを受け取ります。
    panelOpenapp(panel)
    openedpanel(panel)イベントは、Panel がそのオープニングアニメーションを完了したときに発生します。As an argument event handler receive panel instance
    panelOpenedapp(panel)
    closepanel(panel)イベントは、Panel が閉じるアニメーションを開始したときに発生します。引数のイベントハンドラがパネルインスタンスを受け取ると
    panelCloseapp(panel)
    closedpanel(panel)イベントは、Panel が閉じるアニメーションを完了したときに発生します。As an argument event handler receive panel instance
    panelClosedapp(panel)
    backdropClickpanel(panel)パネルの背景がクリックされるとイベントが発生します。イベントハンドラーがパネルインスタンスを受け取ると
    panelBackdropClickapp(panel)
    swipeOpenpanel(panel)スワイプで開いた最初の段階でイベントが発生します。As an argument event handler receive panel instance
    panelSwipeOpenapp(panel)
    swipepanel(panel, progress)スワイプパネルがタッチ・スワイプされた時にイベントが発生します。As an argument event handler receive panel instance and opened progress (from 0 to 1)
    panelSwipeapp(panel, progress)
    collapsedBreakpointpanel(panel)アプリの幅とパネルの collapsedBreakpoint が一致した時に、パネルが表示/非表示になるとイベントが発生します。イベントハンドラはパネルインスタンスを引数として受け取ります。
    panelCollapsedBreakpointapp(panel)
    breakpointpanel(panel)イベントはアプリの幅が visibleBreakpoint と一致した時に表示/非表示になるとトリガーされます。パネルのインスタンスを受け取るイベントハンドラの引数として
    panelBreakpointapp(panel)
    resizepanel(panel, newPanelWidth)イベントはサイズ変更可能なパネルのリサイズ時にトリガーされます。
    panelResizeapp(panel)
    beforeDestroypanel(panel)イベントは、パネルインスタンスが破棄される直前に発生します。
    panelBeforeDestroyapp(panel)

    パネルの自動初期化

    Panel API を使用する必要がなく、Panel がアプリの init 時やページの内部にあり、ページの初期化時に DOM に表示される場合は、追加の panel-init クラスを追加するだけで、自動的に初期化することができます。

    <!-- panel-initクラスの追加 -->
    <div class="panel panel-left panel-cover panel-init">
      ...
    </div>

    この場合、作成された Panel インスタンスにアクセスする必要がある場合は、app.panel.get アプリメソッドを使用できます。

    var panel = app.panel.get('.panel-left');
    
    if (panel.opened) {
      // 何かをする
    }

    自動 init を使用する場合、追加のパラメータを渡す必要があるかもしれません。これは、Panel要素のdata-属性で行うことができます。

    <!-- data-属性で設定するパラメータ -->
    <div
      class="panel panel-left panel-reveal panel-init"
      data-collapsed-breakpoint="768"
      data-visible-breakpoint="1024"
      data-swipe="true"
    >
      ...
    </div>

    キャメルケースで使われているパラメータ、例えばvisibleBreakpointは、data-属性ではdata-visible-breakpointとしてケバブケースで使われるべきです。

    リンク付きコントロールパネル

    リンク上の特別なクラスとデータ属性を使って、(DOMにパネルがある場合)必要なパネルを開いたり閉じたりすることができます。

    • パネルを開くには、panel-open クラスを任意の HTML 要素に追加する必要があります (リンクの方が好ましい)。

    • パネルを閉じるには、任意の HTML 要素に panel-close クラスを追加する必要があります (リンクが好ましい)。

    • パネルを切り替えるには、任意の HTML 要素に panel-toggle クラスを追加する必要があります (リンクが望まれます)。

    • どのパネルを開いたり閉じたりするかを指定したい場合には、このHTML要素に data-panel=".panel-left" 属性を追加することで実現できます。この属性は、DOM内にパネルが1つしかない場合には、leftまたはrightの値だけを受け取ることもできます。

    上記の説明によると

    <body>
      <div id="app">
        <!-- 表示効果のある左パネル -->
        <div class="panel panel-left panel-reveal panel-init">
          <div class="block">
            ...
            <!-- panel-close "クラスのリンクをクリックすると、パネルが閉じます。 -->
            <p><a href="#" class="panel-close">Close me</a></p>
            <!-- panel-open" と data-panel=".panel-right" 属性を持つリンクをクリックすると、右パネルが開きます。 -->
            <p><a href="#" data-panel=".panel-right" class="panel-open">Open Right Panel</a></p>
          </div>
        </div>
    
        <!-- カバー効果のある右パネル -->
        <div class="panel panel-right panel-cover panel-init">
          <div class="block">
            ...
            <!-- panel-close "クラスの付いたリンクをクリックするとパネルが閉じます。 -->
            <p><a href="#" class="panel-close">Close me</a></p>
            <!-- panel-open" and data-panel=".panel-left "属性のリンクをクリックすると、左パネルが開きます。 -->
            <p><a href="#" data-panel=".panel-left" class="panel-open">Open Left Panel</a></p>
          </div>
        </div>
    
        ...
        <div class="page-content">
          <div class="block">
            <!-- panel-open" and data-panel=".panel-left "属性を持つリンクをクリックすると、左パネルが開きます。 -->
            <p><a href="#" data-panel=".panel-left" class="panel-open">Open Left Panel</a></p>
            <!-- panel-open" and data-panel=".panel-right "属性を持つリンクをクリックすると、右パネルが表示されます。 -->
            <p><a href="#" data-panel=".panel-right" class="panel-open">Open Right Panel</a></p>
          </div>
        </div>
      </div>
      ...
    </body>

    ルーティング可能なパネル

    パネルは、ルーティング可能なモーダルやページと同じ機能を持つルーティング可能なパネルにすることができます。

    • いわゆる特別なリンクやAPIではなく、通常のリンクでパネルを開くことができます。
    • ブラウザの履歴を有効にすると、ブラウザを更新したり、履歴を前後に移動したりしたときに、同じパネルが開かれます。
    • ルーティング可能なパネルでは、ページやモーダルと同じ方法、つまり、urlcontentcomponentcomponentUrlを使用して、パネル自体やそのコンテンツをロードすることができます。
    routes = [
      ...
      // 渡された HTML 文字列から Panel を作成します。
      {
        path: '/left-panel/',
        panel: {
          content: `
            <div class="panel panel-left panel-cover">
              <div class="view">
                <div class="page">
                  ...
                </div>
              </div>
            </div>
          `
        }
      },
      // Ajax によるファイルからの Panel の読み込み
      {
        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>
          */
        },
      },
      // コンポーネントファイルからパネルを読み込む
      {
        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>
          */
        },
      },
    ]

    上記の例によると

    • href 属性が /left-panel/ のリンクをクリックすると、指定した文字列のコンテンツからパネルが開かれます。
    • right-panel-ajax/ href 属性を持つリンクをクリックすると、right-panel.html` ファイルへの Ajax リクエストが実行され、右パネルとして開かれます。
    • また、/panel-component/ href 属性を持つリンクをクリックすると、panel-component.html ファイルへの Ajax リクエストが実行され、Router Component として解析され、Panel として開かれます。

    ネストされたパネル

    メインアプリのパネルに加えて、例えばページの中にネストされたパネルを持つことも可能です。パネルを入れ子にするには、親コンテナ(例:Page要素)を指すcontainerElパラメータを指定して、page-content要素の前に置く必要があります。

    <div class="page" id="panel-page">
      <div class="navbar">
        <!-- ... -->
      </div>
    
      <!-- 入れ子になったパネルは、containerElパラメータで指定された親ページを持ちます。 -->
      <div class="panel panel-left panel-cover panel-init theme-dark" id="panel-nested" data-container-el="#panel-page">
        <div class="page">
          <!-- ... -->
        </div>
      </div>
    
      <!-- ページの残りの部分 -->
      <div class="page-content">
        <!-- ... -->
      </div>
    </div>
    

    CSS Variables

    Below is the list of related CSS variables (CSS custom properties).

    Note that commented variables are not specified by default and their values is what they fallback to in this case.

    :root {
      --f7-panel-width: 260px;
      /*
      --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;
    }
    .ios {
      --f7-panel-collapsed-width: 58px;
      --f7-panel-backdrop-bg-color: rgba(0, 0, 0, 0);
      --f7-panel-transition-duration: 400ms;
      --f7-panel-shadow: transparent;
    }
    .md {
      --f7-panel-collapsed-width: 60px;
      --f7-panel-backdrop-bg-color: rgba(0, 0, 0, 0.3);
      --f7-panel-transition-duration: 300ms;
      --f7-panel-shadow: rgba(0, 0, 0, 0.2) 0%,
        rgba(0, 0, 0, 0.07) 30%,
        rgba(0, 0, 0, 0.03) 40%,
        rgba(0, 0, 0, 0) 60%,
        rgba(0, 0, 0, 0) 100%;
    }
    .aurora {
      --f7-panel-collapsed-width: 60px;
      --f7-panel-backdrop-bg-color: rgba(0, 0, 0, 0.3);
      --f7-panel-transition-duration: 300ms;
      --f7-panel-shadow: rgba(0, 0, 0, 0.2) 0%,
        rgba(0, 0, 0, 0.07) 30%,
        rgba(0, 0, 0, 0.03) 40%,
        rgba(0, 0, 0, 0) 60%,
        rgba(0, 0, 0, 0) 100%;
    }
    

    Examples

    <template>
      <div id="app">
        <div class="panel panel-left panel-left-1 panel-reveal panel-resizable panel-init">
          <div class="block">
            <p>Left Panel content here</p>
            <p><a class="panel-close" href="#">Close me</a></p>
            <p><a class="panel-open" href="#" data-panel=".panel-right-1">Open Right Panel</a></p>
          </div>
        </div>
        <div class="panel panel-left panel-left-2 panel-push panel-resizable panel-init">
          <div class="block">
            <p>Here comes another left panel with "push" effect.</p>
          </div>
        </div>
        <div class="panel panel-right panel-right-1 panel-cover panel-resizable panel-init">
          <div class="block">
            <p>Right Panel content here</p>
            <p><a class="panel-close" href="#">Close me</a></p>
            <p><a class="panel-open" href="#" data-panel="left">Open Left Panel</a></p>
          </div>
        </div>
        <div class="panel panel-right panel-right-2 panel-cover panel-init theme-dark">
          <div class="page">
            <div class="block">
              <p>Here comes another right panel.</p>
              <p><a class="panel-close" href="#">Close me</a></p>
            </div>
          </div>
        </div>
        <div class="view view-main view-init">
          <div class="page" id="panel-page">
            <div class="navbar">
              <div class="navbar-bg"></div>
              <div class="navbar-inner">
                <div class="title">Panels</div>
              </div>
            </div>
    
            <!-- Nested panel -->
            <div class="panel panel-left panel-cover panel-init theme-dark" id="panel-nested"
              data-container-el="#panel-page">
              <div class="page">
                <div class="page-content">
                  <div class="block block-strong">
                    <p>This is page-nested Panel.</p>
                    <p><a href="#" class="panel-close">Close me</a></p>
                  </div>
                </div>
              </div>
            </div>
    
            <div class="page-content">
              <div class="block block-strong">
                <p><a class="button button-fill panel-open" href="#" data-panel=".panel-left-1">Left Panel</a></p>
                <p><a class="button button-fill panel-open" href="#" data-panel=".panel-left-2">Left Push Panel</a></p>
                <p><a class="button button-fill panel-open" href="#" data-panel=".panel-right-1">Right Panel</a></p>
                <p><a class="button button-fill panel-open" href="#" data-panel=".panel-right-2">Another Right Panel</a></p>
                <p><a class="button button-fill panel-open" href="#" data-panel="#panel-nested">Nested panel</a></p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </template>
    <style>
      .panel {
        min-width: 100px;
        max-width: 90vw;
      }
    </style>
    <script>
      export default (props, { $, $f7, $f7ready }) => {
        $f7ready(() => {
          // Dom Events
          $('.panel-left').on('panel:open', function () {
            console.log('Panel left: open');
          });
          $('.panel-left').on('panel:opened', function () {
            console.log('Panel left: opened');
          });
    
          // Instance Events
          var panelRight = $f7.panel.get('.panel-right-1');
          panelRight.on('open', function () {
            console.log('Panel right: open');
          });
          panelRight.on('opened', function () {
            console.log('Panel right: opened');
          });
    
          // App Events
          $f7.on('panelClose', function (panel) {
            console.log('Panel ' + panel.side + ': close');
          });
          $f7.on('panelClosed', function (panel) {
            console.log('Panel ' + panel.side + ': closed');
          });
          $f7.on('panelResize', function (panel, newPanelWidth) {
            console.log('Panel resized to ' + newPanelWidth + 'px');
          });
        })
    
        return $render;
      }
    </script>