图文面板/侧面板

面板布局

让我们看看如何向我们的应用程序添加侧边栏。我们最多可以向我们的应用程序添加 2 个面板,一个在左侧,另一个在右侧。我们应该在应用程序根元素的开头处添加面板的 HTML(或者在没有使用根元素的情况下使用 <body>

<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 - object. 面板参数对象

方法返回创建的面板实例

app.panel.destroy(el)-销毁面板实例

  • el - HTMLElementstring (带有 CSS 选择器) 或 object. 要销毁的面板元素或面板实例。

app.panel.get(el)-通过 HTML 元素获取面板实例

  • el - HTMLElementstring (带有 CSS 选择器). 面板元素。

方法返回面板实例

app.panel.open(panel, animate)-打开面板

  • panel - HTMLElementstring (带有 CSS 选择器) 要打开的面板元素
  • animate - boolean. 是否使用动画打开。可选,默认为 true

app.panel.close(panel, animate)-关闭面板

  • panel - HTMLElementstring (带有 CSS 选择器) 要关闭的面板元素
  • animate - boolean. 是否使用动画关闭。可选,默认为 true

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

  • panel - HTMLElementstring (带有 CSS 选择器) 要切换的面板元素
  • animate - boolean. 是否使用动画打开/关闭。可选,默认为 true

边栏参数

如果我们使用 app.panel.create 方法手动创建边栏,我们需要传递包含边栏参数的对象

参数类型默认描述
elHTMLElement
字符串
边栏元素
resizable布尔启用可调整大小的边栏。如果没有传递,则将根据 panel-resizable 类确定。
visibleBreakpoint数字当左面板始终可见时的最小应用宽度(以 px 为单位)
collapsedBreakpoint数字当左面板部分可见(折叠)时的最小应用宽度(以 px 为单位)
swipe布尔false如果要启用通过滑动打开/关闭边栏的功能,则启用
swipeNoFollow布尔false在旧设备/速度较慢的设备上可能会提高性能的备用选项。如果您启用它,那么滑动边栏在触屏移动期间不会跟随您的手指,它将在向左/向右滑动时自动打开/关闭。
swipeActiveArea数字0触发边栏滑动的屏幕上的无形区域的宽度(以 px 为单位)
swipeOnlyClose布尔false此参数允许通过滑动关闭(但不打开)边栏。(swipe 也应启用)
swipeThreshold数字0如果“触摸距离”小于此值(以 px 为单位),边栏将不会随着滑动而移动。
backdrop布尔true启用边栏背景(后面有深色半透明层)
backdropElHTMLElement
字符串
HTML 元素或自定义背景元素的字符串 CSS 选择器
closeByBackdropClick布尔true启用/禁用通过单击边栏外部关闭边栏的功能
containerElHTMLElement
字符串
允许将边栏安装到自定义元素,而不是应用根元素
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,
  }
});

边栏方法和属性

在创建边栏实例(通过调用 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 - 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)在实例上触发事件

面板事件

面板将在面板元素和应用程序及面板实例上触发下列 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 实例同时在自身实例和应用实例上派发事件。应用实例事件有以 panel 开头的相同名称。

事件目标参数描述
openpanel(panel)当 Panel 开始其打开动画时将触发事件。作为参数,事件处理程序接受 panel 实例
panelOpenapp(panel)
openedpanel(panel)当 Panel 完成其打开动画时将触发事件。作为参数,事件处理程序接受 panel 实例
panelOpenedapp(panel)
closepanel(panel)当 Panel 开始其关闭动画时将触发事件。作为参数,事件处理程序接受 panel 实例
panelCloseapp(panel)
closedpanel(panel)当 Panel 完成其关闭动画时将触发事件。作为参数,事件处理程序接受 panel 实例
panelClosedapp(panel)
backdropClickpanel(panel)当点击 panel 背景时将触发事件。作为参数,事件处理程序接受 panel 实例
panelBackdropClickapp(panel)
swipeOpenpanel(panel)当它用滑动手势打开时将在其开始时触发事件。作为参数,事件处理程序接受 panel 实例
panelSwipeOpenapp(panel)
swipepanel(panel, progress)将为在触碰滑动操作期间刷动的 panel 触发事件。作为参数,事件处理程序接受 panel 实例和打开进度(从 0 到 1)
panelSwipeapp(panel, progress)
collapsedBreakpointpanel(panel)当应用宽度与其 collapsedBreakpoint 匹配时,当它变为可见或隐藏时将触发事件。作为参数,事件处理程序接受 panel 实例
panelCollapsedBreakpointapp(panel)
breakpointpanel(panel)当应用宽度与其 visibleBreakpoint 匹配时,当它变为可见或隐藏时将触发事件。作为参数,事件处理程序接受 panel 实例
panelBreakpointapp(panel)
resizepanel(panel, newPanelWidth)在可调整大小的面板大小调整时触发事件
panelResizeapp(panel)
beforeDestroypanel(panel)在面板实例即将被销毁之前,将触发事件
panelBeforeDestroyapp(panel)

Panel 自动初始化

如果您不需要使用 Panel API,而且您的 Panel 在初始化时位于应用中或在页面中,并且在页面初始化时提供在 DOM 中,那么只需添加额外的 panel-init 类即可自动初始化。

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

在这种情况下,如果您需要访问已创建的 Panel 实例,则可以使用 app.panel.get 应用方法

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

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

当使用自动初始化时,您可能需要传递额外的参数。这可以通过 panel 元素上的 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>

以驼峰式命名法使用的参数,例如 visibleBreakpoint,在 data- 属性中应该以连接号分隔的形式使用,如 data-visible-breakpoint

可以使用链接上的特殊类和 data 属性打开和关闭所需的 panel(如果它们在 DOM 中)

  • 要打开 panel,我们需要向任何 HTML 元素(最好指向链接)添加 panel-open

  • 要关闭面板,我们需要将 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>