页面

页面是显示应用程序内容时使用的主要组件(容器)之一。

页面布局

<div class="page" data-name="home">
  <div class="page-content">
    ... scrollable page content goes here ...
  </div>
</div>

页面名称

你可能已经注意到,每个页面都带有具有唯一页面名称的data-name属性。这并非必需,但可以在“页面事件”或“页面回调”中派上用场。它可以帮助我们定义哪个页面已加载并可用,这样你就可以对页面执行必要的操作。

页面内容

所有可视内容(如列表视图、表单等)都应放入<div class="page-content">,而这应是<div class="page">的子级。实现正确样式、布局和滚动是必要的。

页面事件

现在我们来了解页面导航中最重要的一部分“页面事件” 。页面事件允许我们通过为那些特定页面执行 JavaScript 来操纵刚加载的页面。

事件目标说明
page:mounted页面元素<div class="page">当新页面刚插入到 DOM 时,将会触发事件。或者当具有keepAlive路由的页面已挂载到 DOM 时。
page:init页面元素<div class="page">当 Framework7 初始化必需的页面组件和导航栏后,将会触发事件。
page:reinit页面元素<div class="page">如果页面导航到已初始化的页面,将会触发此事件。
page:beforein页面元素<div class="page">当所有内容初始化完毕,且页面已准备好过渡到视图(转变为正在活动/当前位置)时,将会触发事件。
page:afterin页面元素<div class="page">当页面过渡到视图后,将会触发事件。
page:beforeout页面元素<div class="page">页面准备从视图中移除之前,将会触发事件。
page:afterout页面元素<div class="page">当页面从视图中移除后,将会触发事件。
page:beforeunmount页面元素<div class="page">当具有keepAlive路由的页面准备从 DOM 中移除时,将会触发事件。
page:beforeremove页面元素<div class="page">在页面从 DOM 中删除之前,将会触发事件。当你需要分离一些事件/销毁某些插件以释放内存时,此事件非常有用。对于keepAlive路线,不会触发此事件。
page:tabshow页面元素<div class="page">当页面的父以选项卡形式显示变得可见时,将会触发事件。
page:tabhide页面元素<div class="page">当页面的父以选项卡形式显示变得隐藏时,将会触发事件。

让我们看看如何利用这些事件。有两种添加页面事件处理程序的方法。

// Option 1. Using one 'page:init' handler for all pages
$$(document).on('page:init', function (e) {
  // Do something here when page loaded and initialized
})

// Option 2. Using live 'page:init' event handlers for each page
$$(document).on('page:init', '.page[data-name="about"]', function (e) {
  // Do something here when page with data-name="about" attribute loaded and initialized
})

页面加载顺序类

当新页面加载并过渡到视图(应用程序的主要可见部分)时,页面元素上具有不同的类。

当我们加载/打开新页面时,会出现以下情况:

  1. 当前正在活动的页面具有page-current类。
  2. 如果我们加载的页面不在 DOM 中(例如,通过 Ajax 加载或使用模板或组件加载),则将其添加到 DOM。
  3. 我们加载/打开的页面将在其元素上额外设置page-next类。
  4. 路由元素(<div class="view">)将额外具有以下内容router-transition-forward类,该类执行以下操作:
    • 具有page-next(新页面)类的页面移至视图
    • 带有 page-current(当前页面)类的页面移出视图
  5. 转换完成后,我们加载的新页面将具有 page-current
  6. 之前处于活动状态的页面将具有 page-previous

当我们加载/打开前一页(返回)时,会发生以下情况

  1. 当前正在活动的页面具有page-current类。
  2. 如果我们返回的页面不在 DOM 中(例如,通过 Ajax 或使用模板或从组件加载),它将被添加到 DOM 中。
  3. 我们返回的页面将在其元素上设置附加的 page-previous 类。
  4. Router 元素 (<div class="view">) 将具有附加的 router-transition-backward 类,它执行以下操作
    • 带有 page-previous(我们返回的页面)类的页面移入视图
    • 带有 page-current(当前页面)类的页面移出视图
  5. 转换完成后,我们返回的新页面将具有 page-current
  6. 之前处于活动状态的页面将具有 page-next 类。如果此页面是动态添加到 DOM 中的,它将从 DOM 中删除。

页面数据

正如您所见,这很容易,但是我们仅使用一个处理程序时如何确定加载了哪个页面?对于这种情况,我们在事件详细信息中具有页面数据

// In page events:
$$(document).on('page:init', function (e) {
  // Page Data contains all required information about loaded and initialized page
  var page = e.detail;
})

或者,如果使用 Dom7 分配了事件处理程序,如上面的示例,则将其作为第二个参数传递

// In page events:
$$(document).on('page:init', function (e, page) {
  console.log(page);
})

现在,在上面的示例中,我们在 page 变量中具有页面数据。它是一个具有以下属性的对象

page.app对象已初始化的应用实例
page.view对象包含此页面的视图实例(如果已初始化此视图)
page.router对象包含此页面的 Router 实例(如果已初始化此视图)。与 page.view.router 相同
page.name字符串页面的 data-name 属性的值
page.elHTMLElement页面元素
page.$el对象带有页面元素的 Dom7 实例
page.from字符串转换前的页面位置或此页面来自的方向。如果您加载新页面,它将为 next,如果您返回此页面,它将为 previous,如果您返回此页面,它将为 next,如果您返回此页面,它将为 nextcurrent 如果此页面替换当前活动页面。
page.to字符串新页面位置或此页面转到何处。可以是相同的 nextpreviouscurrent
page.position字符串page.from 的别名
page.direction字符串页面转换的方向(如果适用)。可以是 forwardbackward
page.route对象与此页面关联的路由,带有用于加载此页面的当前路由数据的对象。它具有以下属性
  • url - 路由 URL
  • path - 路由路径
  • query - 带有路由查询的对象。如果 url 是 /page/?id=5&foo=bar 那么它将包含以下对象 {id: '5', foo: 'bar'}
  • params - 路由参数。如果我们的匹配路由有 /page/user/:userId/post/:postId/ 路径,页面的 URL 是 /page/user/55/post/12/,那么它将是以下对象 {userId: '55', postId: '12'}
  • name - 路由名称
  • hash - 路由 URL 哈希
  • route - 从可用路由中匹配路由的对象
  • context - 传递给路由的上下文
page.pageFrom对象此新页面前当前处于活动状态的页面的页面数据。

访问页面数据

如果您不使用页面事件/回调,并且需要访问页面数据,可以通过其 HTMLElement 上的 f7Page 属性来访问

var $$ = Dom7;

var page = $$('.page[data-name="somepage"]')[0].f7Page;

// do something with page data

CSS 变量

以下是相关 CSS 变量(CSS 自定义属性)的列表。

请注意,带注释的变量在默认情况下未指定,并且它们的回退值是它们在这种情况下回退到的内容。

:root {
  --f7-page-master-width: 320px;
  --f7-page-master-border-color: rgba(0, 0, 0, 0.1);
  --f7-page-master-border-width: 1px;
  --f7-page-swipeback-transition-duration: 300ms;
  --f7-page-parallax-transition-duration: 500ms;
  --f7-page-cover-transition-duration: 450ms;
  --f7-page-dive-transition-duration: 500ms;
  --f7-page-fade-transition-duration: 500ms;
  --f7-page-flip-transition-duration: 700ms;
  --f7-page-push-transition-duration: 500ms;
  /*
  --f7-page-content-extra-padding-top: 0px;
  --f7-page-content-extra-padding-bottom: 0px;
  */
  --f7-page-title-line-height: 1.2;
  --f7-page-title-text-color: inherit;
  --f7-page-title-padding-left: 16px;
  --f7-page-title-padding-right: 16px;
}
.ios {
  --f7-page-transition-duration: 400ms;
  --f7-page-title-font-size: 34px;
  --f7-page-title-font-weight: 700;
  --f7-page-title-letter-spacing: -0.03em;
  --f7-page-title-padding-vertical: 6px;
  --f7-page-bg-color: #efeff4;
}
.ios .dark,
.ios.dark {
  --f7-page-bg-color: #000;
}
.md {
  --f7-page-transition-duration: 400ms;
  --f7-page-title-font-size: 34px;
  --f7-page-title-font-weight: 500;
  --f7-page-title-letter-spacing: 0;
  --f7-page-title-padding-vertical: 8px;
}
.md,
.md .dark,
.md [class*='color-'] {
  --f7-page-bg-color: var(--f7-md-surface);
}
.dark {
  --f7-page-master-border-color: rgba(255, 255, 255, 0.2);
}