Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

Framework7学习笔记(一):基础

27
Dec
2015

Framework7学习笔记(一):基础

By Alex
/ in HTML,JavaScript,Mobile
/ tags F7, 学习笔记
0 Comments
Framework7简介

Framework7(以下简称F7)是用于开发具有iOS/Android原生外观的混合移动应用/Web应用的开源框架,同时它也可以作为快速原型工具使用。F7完全基于Web技术——HTML、CSS、JavaScript。

F7简单易用,我们可以仅仅编写常规的HTML,不需要开发定制的标签(Angular那样),或者通过JavaScript来描述我们的页面(ExtJS那样)。

F7原先专注于iOS平台,现在也支持Google的Material design specification——Android平台的UI设计规范。

F7内置了大量的组件,例如模态窗口、侧面板、表格、表单、列表等等,使用这些组件时,几乎不需要编写JavaScript。

F7的外观易于定制,所有样式被分离在较小的 .less 文件中。我们可以基于Less.js修改和编译样式。

F7还包括更多的特性:

  1. 原生的滚动效果(Native Scrolling)
  2. 不依赖任何第三方框架
  3. 高性能的,基于CSS的动画
  4. 支持缓存、历史、预加载(Preloading)
  5. 支持无限制的多视图,不需要任何JavaScript代码即可控制视图
  6. 简洁的JavaScript API
  7. DOM7:内置的DOM操控库,风格类似于jQuery
起步:第一个F7应用
基本布局:index.html

该页面声明了应用程序基本的布局:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
    <meta name="format-detection" content="telephone=no">
    <meta name="msapplication-tap-highlight" content="no">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <title>第一个F7应用</title>
    <!-- 主题样式表 -->
    <link rel="stylesheet" href="css/framework7.ios.css">
    <!-- 配色样式表 -->
    <link rel="stylesheet" href="css/framework7.ios.colors.css">
    <!-- Path to your custom app styles-->
  </head>
  <body>
    <!-- PhoneGap应用全屏模式下,用于状态栏overlay -->
    <div class="statusbar-overlay"></div>
    <!-- 面板overlay-->
    <div class="panel-overlay"></div>
    <!-- 带reveal特效的左侧面板 -->
    <div class="panel panel-left panel-reveal">
      <div class="content-block">
        <p>这里存放左侧面板的内容</p>
      </div>
    </div>
    <!-- 所有视图 -->
    <div class="views">
      <!-- 主视图,应当包含"view-main"样式类 -->
      <div class="view view-main">
        <!-- 顶部导航栏-->
        <div class="navbar">
          <div class="navbar-inner">
            <!-- 在应用标题上添加sliding效果 -->
            <div class="center sliding">第一个F7应用</div>
            <div class="right">
              <!--
                右侧内容仅仅是一个图标,因此添加icon-only类
                open-panel类提示F7,点击链接时打开面板
              -->
              <a href="#" class="link icon-only open-panel"><i class="icon icon-bars"></i></a>
            </div>
          </div>
        </div>
        <!-- 页面容器,由于使用了fixed-through的导航栏、工具栏,需要添加合适的样式类-->
        <div class="pages navbar-through toolbar-through">
          <!-- 页面,"data-page" 属性包含页面的名称 -->
          <div data-page="index" class="page">
            <!-- 可滚动的页面内容 -->
            <div class="page-content">
              <p>页面内容</p>
              <a href="about.html">关于</a>
            </div>
          </div>
        </div>
        <!-- 底部的工具栏 -->
        <div class="toolbar">
          <div class="toolbar-inner">
            <!-- 工具栏链接-->
            <a href="#" class="link">链接1</a>
            <a href="#" class="link">链接2</a>
          </div>
        </div>
      </div>
    </div>
    <!-- Cordova的JavaScript占位符-->
    <script type="text/javascript" src="cordova.js"></script>
    <!-- Framework7的JavaScript文件 -->
    <script type="text/javascript" src="js/framework7.js"></script>
    <!-- 当前应用的JavaScript文件 -->
    <script type="text/javascript" src="js/index.js"></script>
  </body>
</html>
页面片段:about.html
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- 我们不需要在此页面中定义完整的布局,该页面是通过Ajax解析并纳入DOM的。这种做法和AngularJS的ngInclude类似 -->
 
<!-- 顶部导航栏 -->
<div class="navbar">
    <div class="navbar-inner">
        <div class="left">
            <a href="#" class="back link"> <i class="icon icon-back"></i> <span>返回</span>
            </a>
        </div>
        <div class="center sliding">关于</div>
        <div class="right">
            <a href="#" class="link icon-only open-panel"><i class="icon icon-bars"></i></a>
        </div>
    </div>
</div>
<!-- 声明页面 -->
<div class="pages">
    <!-- about页面 -->
    <div data-page="about" class="page">
        <div class="page-content">
            <div class="content-block">
                <p>关于本应用</p>
            </div>
        </div>
    </div>
</div>
脚本:index.js

初始化应用和视图:

index.js
JavaScript
1
2
3
4
5
6
7
8
9
10
11
// 初始化F7应用程序
var app = new Framework7();
 
// 快捷方式,用于操控DOM
var $$ = Dom7;
 
// 添加布局中声明的主视图
var mainView = app.addView( '.view-main', {
    // 启用动态导航栏
    dynamicNavbar : true
} );

如果要针对某个页面的添加脚本,可以:

index.js
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 推荐的方式:使用onPageInit回调
app.onPageInit( 'about', function( page ) {
    // 在这里操控about页面
} );
 
// 另外一种方式,针对所有页面的pageInit事件处理器
$$( document ).on( 'pageInit', function( e ) {
    // 从事件中获得页面信息
    var page = e.detail.page;
 
    if ( page.name === 'about' ) {
        // 在这里操控about页面
    }
    ;
} );
 
// 或者,使用活动的pageInit事件处理器
$$( document ).on( 'pageInit', '.page[data-page="about"]', function( e ) {
    // 在这里操控about页面
} );
运行效果

f7-firstapp

 Framework7核心
Dom7

在DOM操控方面,F7没有使用第三方库,而是自己实现了一个称为DOM7的组件。该组件的接口风格类似于jQuery:

JavaScript
1
2
3
4
var $$ = Dom7;
$$( '.something' ).on( 'click', function( e ) {
    $$( this ).addClass( 'hello' ).attr( 'title', 'world' ).insertAfter( '.something-else' );
} );
Dom7常用方法

下面的方法均属于元素集——即 Dom7() 调用的返回值:

方法 说明
addClass() 添加样式类:
JavaScript
1
2
//为所有p元素添加intro类
$$('p').addClass('intro');
removeClass() 移除样式类:
JavaScript
1
2
//从所有具有big样式类的a元素上移除big样式类
$$('a.big').removeClass('big');
hasClass() 判断是否存在至少一个匹配元素具有样式类:
JavaScript
1
$$('p').hasClass('intro');
toggleClass() 如果匹配元素上有指定样式类,移除;反之则添加:
JavaScript
1
$$('h1, h2').toggleClass('small');
prop()  读取或者写入Property:
JavaScript
1
2
3
4
5
6
7
8
var isChecked = $$('input').prop('checked'); //读取
//设置所有checkbox为选中
$$('input[type="checkbox"]').prop('checked', true);
//设置多个属性
$$('input').prop({
  checked: false,
  disabled: true
});
attr() 读取或者写入Attribute,Attribute与Property类似,但是前者相当于直接操作XML的属性节点:
JavaScript
1
2
3
4
5
6
7
8
var link = $$( 'a' ).attr( 'href' );
$$( 'a' ).attr( 'href', 'http://google.com' );
$$( 'a' ).attr( {
    id : 'new-id',
    title : 'Link to Google',
    href : 'http://google.com'
} );
$$( 'img' ).removeAttr( 'src' );
val() 得到第一个匹配元素的值,或者设置所有匹配元素的值:
JavaScript
1
2
3
//<input id="myInput" type="text" value="Lorem ipsum"/>
var inputVal = $$('#myInput').val();
$$('input#myInput').val('New value here');
data() 读取第一个匹配元素上存储的(任意)数据,或者写入所有匹配元素的数据:
JavaScript
1
2
3
4
5
6
7
8
$$( 'a' ).data( 'user', {
    id : '123',
    name : 'John',
    email : 'john@doe.com'
} );
var user = $$( 'a' ).data( 'user' );
// {id: '123', name: 'John', email: 'john@doe.com'}
$$( 'a' ).removeData( 'user' );
dataset() 返回元素上定义的数据集(即data- 属性)为简单对象:
XHTML
1
2
3
4
5
6
7
8
9
10
11
12
<div id="my-div" data-loop="true" data-animate-pages="false" data-index="0" data-hello="world"></div>
<script type="text/javascript">
var dataset = $$('#my-div').dataset();
/**
{
    loop: true,
    animatePages: false,
    index: 0,
    hello: 'world'
}
*/
</script>
transform() 添加CSS转换属性:
JavaScript
1
$$('a').transform('rotate(90deg)')
transition() 设置CSS变换持续时间:
JavaScript
1
$$('p').transition(300)
on() 注册事件处理器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 函数签名:
function on(eventName, handler, useCapture);
// delegatedTarget被代理事件源
function on(eventName, delegatedTarget, handler, useCapture);
//用法示例:
$$('a').on('click', function (e) {
    console.log('clicked');
});
//同时监听多种事件
$$('input[type="text"]').on('keyup keydown change', function (e) {
    console.log('input value changed');
});
//代理事件处理器
$$(document).on('click', 'a', function (e) {
    console.log('link clicked');
});
once() 注册只执行一次的事件处理器
off() 移除事件处理器:
JavaScript
1
2
3
4
5
6
//函数签名
function off(eventName, handler, useCapture);
function off(eventName, delegatedTarget, handler, useCapture);
 
//移除一个事件处理器,clickHandler必须已经注册为处理器
$$('a').off('click', clickHandler);
trigger() 触发匹配元素上指定事件,并执行所有已注册的事件处理器:
JavaScript
1
2
//函数签名
function trigger(eventName, eventData);
transitionEnd() 添加CSS变换结束处理器:
JavaScript
1
$$('a').transitionEnd(function(){  })
animationEnd() 添加动画效果结束处理器:
JavaScript
1
$$('a').animationEnd(function(){  })
width() 得到第一个匹配元素的实际宽度
outerWidth() 得到第一个匹配元素的宽度,包括补白和边框,如果入参true,则还包括margin
height() 得到第一个匹配元素的实际高度
outerHeight() 得到第一个匹配元素的高度,包括补白和边框,如果入参true,则还包括marg
offset() 得到第一个匹配元素相对于document的偏移量:
JavaScript
1
2
var coords = $$('.content').offset();
// {top: 100, left: 200}
hide() 设置 display:none 以隐藏所有匹配元素
show() 设置 display:block 以显示所有匹配元素
css() 获取或者设置CSS属性:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
//得到left属性
$$('.content').css('left');
//设置left属性
$$('.content').css('left', '100px');
//设置多个CSS属性
$$('a').css({
    left: '100px',
    top: '200px',
    color: 'red',
    width: '300px',
    marginLeft: '17px', //驼峰式转写
    'padding-right': '20px' //原始样式名称,非法标识符需要引号
});
scrollTop() 滚动元素
scrollLeft()
scrollTo()
add() 添加元素到既有的Dom7元素集中:
JavaScript
1
2
3
var links = $$('a');
links.add('p').addClass('blue');
links.add($$('div')).addClass('red');
each() 迭代元素集合,执行回调函数
html() 得到第一个元素的HTML内容,或者设置所有匹配元素的HTML内容
text() 得到第一个元素的文本内容,或者设置所有匹配元素的文本内容
is() 判断当前元素集是否匹配指定的CSS选择器、HTML元素或者Dom7元素集合:
JavaScript
1
2
$$('div').is(CSSSelector);
$$('div').is(HTMLElement);
index() 得到第一个元素在其兄弟元素中的相对索引
eq(idx) 获得元素集中第idx个元素
append() 在元素集所有元素的结尾插入指定的HTML元素或者HTML字符串
appendTo(el) 把元素集插入到el元素的结尾
prepend() 在元素集所有元素的起始处插入指定的HTML元素或者HTML字符串
prependTo(el) 把元素集插入到el元素的起始处
insertBefore(tgt) 在目标(CSS选择器、HTML元素、Dom7元素集)之前插入当前匹配的元素集
insertAfter(tgt) 在目标(CSS选择器、HTML元素、Dom7元素集)之后插入当前匹配的元素集
next([sel]) 获得元素集每个元素的下一个弟弟元素,如果提供selector,则仅返回匹配此选择器的弟弟元素
nextAll([sel]) 获得元素集每个元素的全部弟弟元素,如果提供selector,则仅返回匹配此选择器的弟弟元素
prev([sel]) 获得元素集每个元素的下一个哥哥元素,如果提供selector,则仅返回匹配此选择器的哥哥元素
prevAll([sel]) 获得元素集每个元素的全部哥哥元素,如果提供selector,则仅返回匹配此选择器的哥哥元素
parent([sel]) 获得元素集每个元素的第一个匹配选择器的祖先元素
parents([sel]) 获得元素集每个元素的所有匹配选择器的祖先元素
find([sel]) 获得元素集每个元素的所有匹配选择器的后代元素
children([sel]) 获得元素集每个元素的所有匹配选择器的儿子元素
filter(callback) 过滤当前元素集:
JavaScript
1
2
3
var redLinks = $$('a').filter(function(index, el) {
    return $$(this).hasClass('red');
})    
remove() 从DOM树中移除当前元素集
Dom7事件快捷方法 

下表是一系列事件处理的快捷方式,它们都属于元素集对象。调用 event() 手工触发指定事件,调用 event(handleFunc) 则注册事件监听器:

blur focus focusin focusout
click keyup keydown keypress
mouseenter mouseover mousedown mousemove
mouseout mouseleave mouseup submit
touchstart touchend touchmove change
resize scroll    
Dom7工具函数

下列函数都直接定义在Dom7上:

函数 说明
each() 遍历“可迭代对象”,函数签名: Dom7.each(object/array, callback); 
示例:
JavaScript
1
2
3
4
5
6
7
8
var fruits = ['Apple', 'Orange', 'Pineapple', 'Bannana'];
$$.each(fruits, function (index, value) {});  
var person = {
    firstName: 'Alex',
    lastName: 'Wong',
    age: 25,
};
$$.each(person, function (key, value) {});
parseUrlQuery() 解析URL并提取请求参数:
JavaScript
1
2
var query = $$.parseUrlQuery('http://google.com/?id=5&foo=bar');
console.log(query); //-> {id: 5, foo: 'bar'}
isArray() 判断一个对象是否为数组
unique() 返回数组的一个去重副本
serializeObject() 以URL请求参数的形式串行化一个简单对象(PO)
toCamelCase() 从短横线连接风格(web-app)转换为驼峰式大小写(webApp)
dataset() 将元素(CSS选择器)中的data-*属性转换为简单对象(PO)
Ajax支持

我们可以调用 $$.ajax(parameters) 来发送Ajax请求并处理结果,其中parameters会一个配置对象,可以指定以下属性:

属性 说明
async 是否异步发送请求,默认true
url 请求的目标地址
method 请求使用的HTTP方法,默认'GET'
cache 是否允许浏览器缓存请求,默认true。如果设置为false则自动添加 _nocache={timestamp} 到GET请求参数
contentType 内容类型,默认'application/x-www-form-urlencoded',还可以指定为'multipart/form-data'、'text/plain'。
对于跨域请求,如果设置contentType为前述三者之外的任意值,会导致浏览器发送preflight的OPTIONS请求到服务器
crossDomain 如果要对本域强制使用跨站请求,可以设置为true
data 需要发送给服务器的数据,对于GET请求,会编码为请求参数(除非该参数已经是字符串)附加到URL后面
processData 默认true,设置为false可以阻止Dom7把Object形式的data编码为请求参数形式
dataType 期望服务器返回的数据类型, 默认'text',可以指定为'json'
headers 以键值对形式指定额外的请求头
xhrFields 设置到浏览器原生XHR对象上的键值对
username HTTP验证用户名
password HTTP验证密码
timeout 请求处理超时的毫秒数
beforeSend 在XHR请求发送前执行的回调: function (xhr) ,可以用于修改请求
error 在XHR请求执行失败后执行的回调: function (xhr, status) 
success 在XHR请求执行成功后执行的回调: function (data, status, xhr) 
如果dataType设置为json,那么data自动转换为JavaScript对象,转换失败则status显示为parseerror
Framework7要求严格规范的JSON格式
complete 在XHR请求处理完毕后执行的回调,该回调在error/success之后执行: function (xhr, status) 
statusCode 指定不同HTTP状态码对应的回调:
JavaScript
1
2
3
4
5
6
7
8
$$.ajax({
  url: 'somepage.html',
  statusCode: {
    404: function (xhr) {
      alert('page not found');
    }
  }
});

为了简化常用类型的XHR请求的发送,Dom7提供以下快捷函数:

函数 说明
Dom7.get() 这三个函数都接受三个入参:
  1. url,请求的URL
  2. data,发送给服务器的对象或者字符串
  3. 处理成功后的回调函数: function (data, status, xhr) 
Dom7.post()
Dom7.getJSON()

下表列出Dom7扩展的,全局的Ajax监听事件。这些事件都从 document 对象上发出:

事件 说明
ajaxStart 在XHR请求发送前触发,可以全局性的修改请求,例如添加请求头
ajaxError 当任何XHR请求处理失败时触发
ajaxSuccess 当任何XHR请求处理成功时触发
ajaxComplete 当任何XHR请求处理完毕后触发,该事件在ajaxError/ajaxSuccess之后触发

使用上述事件的例子如下:

JavaScript
1
2
3
4
$$(document).on('ajaxComplete', function (e) {
  var xhr = e.detail.xhr;
  console.log('request performed');
});
布局

F7框架的文档中多次提到布局(Layout)这一个词,在这里布局是指应用程序或者F7组件的HTML结构。

应用程序HTML布局

开发F7应用的第一步,就是创建包含应用程序骨架的index.html文件,此文件包含了应用程序的基本布局。

iOS的基础布局样例可以参考前面的章节,Android Material风格的布局,与iOS稍微不同:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div data-page="index" class="page">
 
    <!-- 顶部导航栏需要置于页的内部 -->
    <div class="navbar">
        <div class="navbar-inner">
            <div class="center">Awesome App</div>
        </div>
    </div>
 
    <!-- 底部工具栏需要置于页的内部 -->
    <div class="toolbar">
      <div class="toolbar-inner">
          <!-- Toolbar links -->
          <a href="#" class="link">Link 1</a>
          <a href="#" class="link">Link 2</a>
      </div>
    </div>
</div>
应用初始化 

可以调用下面的函数初始化F7应用,变量app代表了F7应用的实例:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var app = new Framework7( { /* 唯一的入参是包含所有初始化参数的对象 */
    // 模态窗口的默认标题
    modalTitle : '消息',
 
    // 启用哈希(#)导航
    pushState : true,
 
    // 在XHR请求前后,分别显示,隐藏指示器
    onAjaxStart : function( xhr ) {
        myApp.showIndicator();
    },
    onAjaxComplete : function( xhr ) {
        myApp.hideIndicator();
    }
} );
应用初始化参数详解

F7提供了大量可用的构造参数,如下表:

参数/属性 类型和默认值 说明
Material Theme主题专用参数
material boolean = false 设置为true则启用Material特有的JS行为
materialPageLoadDelay number = 0 新加载页面动画的启动延迟,单位毫秒
materialRipple boolean = true 启用Material的触碰波痕效果
materialRippleElements string = 
CSS
1
2
3
4
5
6
7
8
9
10
11
.ripple
a.link
a.item-link
.button
.modal-button
.tab-link
.label-radio
.label-checkbox
.actions-modal-button
a.searchbar-clear
.floating-button
启用触碰波痕效果的元素的CSS选择器
materialPreloaderHtml string = 
XHTML
1
2
3
4
5
6
7
8
9
<span class="preloader-inner">
    <span class="preloader-inner-gap"></span>
    <span class="preloader-inner-left">
        <span class="preloader-inner-half-circle"></span>
    </span>
    <span class="preloader-inner-right">
        <span class="preloader-inner-half-circle"></span>
    </span>
</span>
 Material主题预加载器(Preloader)的HTML
缓存
cache boolean = true 是否启用GET方式的Ajax的缓存
cacheDuration number = 1000*60*10 缓存有效期,单位毫秒
cacheIgnore array = [] 那些URL需要禁用缓存
cacheIgnoreGetParameters boolean = false 缓存时是否忽略附在URL后面的参数,如果启用,那么不同查询参数只生成同一个缓存
快速点击库
fastClicks boolean = true Fast clicks是F7内置的组件,移除300ms的click事件触发延迟
fastClicksDelayBetweenClicks number = 50 连续多次click事件的最小间隔
fastClicksDistanceThreshold number = 10 如果轻触/移动(tap/move)的距离大于此值,则click事件不会触发
activeState boolean = true 如果启用,F7为当前被触碰的元素添加active-state样式类
activeStateElemets string = 'a, button, label, span' CSS选择器,指定哪些元素支持activeState配置
tapHold boolean = false 设置为true则启用轻触并保持(tap hold)事件
tapHoldDelay number = 750 在轻触后,必须维持多少ms才触发tap hold事件
tapHoldPreventClicks boolean = true 禁止在tap hold事件之后触发click事件
导航路由
router boolean  = true 设置为false禁用内置的导航路由器
ajaxLinks string = undefined 默认的,F7通过Ajax加载所有 <a> 链接。如果指定该参数,那么只有匹配CSS选择器的元素,才使用Ajax加载
dynamicPageUrl string  ='content-{{index}}' 动态加载页的URL规则,支持占位符:
{{index}}  在导航历史中的索引
{{name}} 页面的 data-page 属性
uniqueHistory boolean = false  设置为true,F7保持视图的导航历史条目的唯一性,重复的条目会被删除
uniqueHistoryIgnoreGetParameters boolean = false 判断导航历史条目唯一性时,是否忽略URL参数
externalLinks string = '.external' CSS选择器,用于指定哪些链接属于“外部链接”,不应当由F7处理
allowDuplicateUrls boolean = false

设置为true,则允许加载与当前活动页URL相同的页
在指向当前页面本身的导航时有用

animateNavBackIcon boolean = false 仅IOS。让后退图标的动画效果更加Native
animatePages boolean = true 设置为false可以禁用页面切换动画
preloadPreviousPage boolean = true swipe back page特性需要启用该选项
preroute function(view, options);

该回调拦截路由默认的load/back动作,可以加载其它页或者做额外的工作

返回false则阻止当前路由

该回调在preprocess之前执行

preprocess function(content, url, next);

导航时,可以在插入DOM之前,修改加载的内容。这意味着我们可以使用自己习惯的客户端模板引擎(例如Template7、AngularJS)

此回调中无法访问传递给页面的上下文,可以通过URL的GET参数向新页面传递信息

执行返回操作时,不会触发该回调

Push State
pushState boolean = false 是否启用#导航,启用时,用户可以点击浏览器的前进、后退按钮,在应用的不同页面之间进行切换
pushStateSeparator string = '#!/' Push State的URL分隔符,URL会呈现为类似 http://gmem.cc/#!/hello.html 的形式
pushStateNoAnimation boolean = false 如果设置为true,在Push State之间导航不会产生动画效果
pushStatePreventOnLoad boolean = true 启用后,应用加载时第一个pop state事件被忽略,可以避免不必要的加载动作
 Swipe back(仅iOS主题)
swipeBackPage boolean = true 启用后,可以用从屏幕左侧边缘滑入的手势切换到上一个页面
swipeBackPageThreshold number = 0 滑动距离最小多少像素后,导致Swipe back操作触发
swipeBackPageActiveArea number = 30 触发Swipe back操作的屏幕左侧边缘的宽度
swipeBackPageAnimateShadow boolean = true 是否在Swipe back时启用阴影效果
swipeBackPageAnimateOpacity boolean = true 是否在Swipe back时启用透明效果
可排序列表
sortable boolean = true 如果不使用可排序列表(sortable lists )特性,可以禁用以提升性能
 Swipeout
swipeout boolean = true 如果不使用swipeout特性,可以禁用以提升性能
swipeoutNoFollow boolean = false 用于老旧设备,可以提升性能
侧面板
swipePanel string = false

可以设置为left(左侧)/right(右侧),默认禁用

启用后,可以通过swipe手势从左侧/右侧打开侧面板

swipePanelCloseOpposite boolean = true 可以关闭对面的面板,即右面板之于左面板
swipePanelOnlyClose boolean = false 仅允许通过swipe关闭面板,而不允许打开
swipePanelActiveArea number = false 触发Swipe面板操作的屏幕左侧边缘的宽度
swipePanelNoFollow boolean = false 用于老旧设备,可以提升性能
swipePanelThreshold number = 0 滑动距离最小多少像素后,导致Swipe 面板操作触发
panelsCloseByOutside boolean = true 是否允许在面板外部轻触,以关闭面板
模态窗口
modalTitle string = 'Framework7' 模态窗口(Alert、Confirm、Prompt)的默认标题
modalButtonOk string = 'OK' OK按钮默认文本
modalButtonCancel string = 'Cancel' Cancel按钮默认文本
modalPreloaderTitle string = 'Loading... ' 正在加载的提示文本
modalCloseByOutside boolean = false 是否允许在外部轻触以关闭模态窗口
actionsCloseByOutside boolean = true 与上一选项类似, 但是用于Action Sheet modal
popupCloseByOutside boolean = true 与上一选项类似, 但是用于Popup modal
modalTemplate string = undefined 用于模态窗口的Template7模板
modalActionsTemplate string  = undefined 用于Action Sheet模块窗口的Template7模板
modalActionsToPopoverTemplate string 用于转换为Popover的Action Sheet的Template7模板
modalUsernamePlaceholder string = 'Username' 用户名输入框的占位符
modalPasswordPlaceholder string = 'Password' 密码输入框的占位符
modalStack boolean = true 禁止同时打开多个模态窗口,如果多个模态窗口被触发,那么最顶层的被关闭后,下层模态窗口才打开
Smart Select
smartSelectOpenIn string = 'page' 智能选择如何被打开
可选值page、popup、picker
smartSelectBackTemplate string =
XHTML
1
2
3
4
5
6
<div class="left sliding">
  <a href="#" class="back link">
    <i class="icon icon-back"></i>
    <span>{{backText}}</span>
  </a>
</div>
智能选择页面后退按钮的HTML模板
smartSelectPopupCloseTemplate string = 
XHTML
1
2
3
4
5
6
<div class="left">
  <a href="#" class="link close-popup">
    <i class="icon icon-back"></i>
    <span>{{closeText}}</span>
  </a>
</div>
智能选择弹框关闭按钮的HTML模板
smartSelectBackText string = 'Back' 后退按钮文本
smartSelectPopupCloseText string = 'Close' 关闭按钮文本
smartSelectPickerCloseText string = 'Done' 完毕按钮文本
smartSelectSearchbar boolean = false 是否启用智能选择的搜索功能
smartSelectBackOnSelect boolean = false 如果启用,当用户选择任意一项后,智能选择页面自动关闭
smartSelectFormTheme string = undefined 智能选择页面/弹框的表单元素使用的颜色主题代码
smartSelectNavbarTheme string = undefined 智能选择页面/弹框的导航栏使用的颜色主题代码
导航栏和工具栏
hideNavbarOnPageScroll boolean = false 如果设置为true,导航栏在页面下滚时自动隐藏,上滚时自动显示
hideToolbarOnPageScroll boolean = false 如果设置为true,工具栏在页面下滚时自动隐藏,上滚时自动显示
hideTabbarOnPageScroll boolean = false 如果设置为true,页签栏(Tabbar)在页面下滚时自动隐藏,上滚时自动显示
仅针对基于Tab Bar的页面布局
showBarsOnPageScrollEnd boolean = true 当滚动到页面底部时,自动显示导航、工具栏
showBarsOnPageScrollTop boolean = true 当滚动到页面顶部时,自动显示导航、工具栏
scrollTopOnNavbarClick boolean = false 如果设置为true,点击导航栏中的'center'元素,自动滚动当前活动页面到最顶部
图片延迟加载
imagesLazyLoadThreshold number  = 0 默认的,图片只有显示在当前屏幕上时,才加载
修改此参数,则图片距离屏幕还剩N像素时就加载
imagesLazyLoadSequential boolean = true 如果启用,图片会顺序的一个个加载
imagesLazyLoadPlaceholder string 正在加载的图片的占位符,默认是一个1像素的图片
通知
notificationTitle string = undefined 仅iOS,所有通知的默认标题
notificationSubtitle string = undefined 仅iOS,所有通知的默认子标题
notificationMedia string = undefined 仅iOS,所有通知的默认媒体(图标或者图片)
notificationHold number = undefined 所有通知默认持续的毫秒数
notificationCloseOnClick boolean = false 设置为true,则点击通知关闭之
notificationCloseIcon boolean = true 仅iOS,设置为true默认显示关闭按钮
notificationCloseButtonText string = 'Close' 仅Material,关闭按钮的默认文本
状态栏(仅iOS主题)
statusbarOverlay boolean = undefined 自动检测全屏模式并处理状态栏overlay,在顶部添加额外的像素以改善UI效果
scrollTopOnStatusbarClick boolean = false 如果设置为true,在状态栏上点击后,当前活动页面滚动到顶部
Template7
template7Pages boolean = false 设置为true,使用Template7来渲染Ajax和动态页面
template7Data object = {} 用于渲染Template7模板的数据
precompileTemplates boolean = false 启用后,F7预编译所有Template7模板
templates object = {} 所有预编译的模板,可以通过该属性访问
页面回调
onPageBeforeInit

function(app, page);

其中:

  1. app为当前F7应用对象
  2. page为操作的页面数据对象

这些参数与对应的页面回调具有类似的功能

当F7插入新的页面到DOM中后,该回调被执行
该回调和pageBeforeInit事件具有一样的效果
onPageInit 当F7初始化被请求页面的组件和导航栏时,该回调被执行
该回调和pageInit事件具有一样的效果
onPageBeforeAnimation 当页面被初始化完毕,准备执行页面/导航栏动画时,该回调被执行
该回调和pageBeforeAnimation事件具有一样的效果
onPageAfterAnimation 当页面/导航栏动画执行完毕后,该回调被执行
该回调和pageAfterAnimation事件具有一样的效果
onPageBeforeRemove 当页面即将从DOM中移除时,该回调被执行
该回调和pageBeforeRemove事件具有一样的效果
onPageBack 在back转换之前,执行该回调,与onPageBeforeAnimation针对new页面不同,该回调是针对old页面(即将被切换掉的页面)
该回调和pageBack事件具有一样的效果
onPageAfterBack 在back转换之后,执行该回调,该回调同样针对old页面,而onPageAfterAnimation针对新页面
该回调和pageAfterBack事件具有一样的效果
Ajax回调
onAjaxStart function(xhr); 在Ajax请求开始前执行的回调,以XHR数据作为参数
onAjaxComplete 在Ajax请求完毕后执行的回调,以XHR数据作为参数
Namespace
viewClass string =  'view' 视图元素(View element)的CSS类名
viewMainClass string = 'view-main' 主视图元素的CSS类名
viewsClass string = 'views' 所有视图元素(Views element)的CSS类名
初始化
init boolean = true 如果设置为false,则必须调用Framework7的 init() 方法手工初始化F7
preprocess:使用模板引擎

通过设置preprocess,我们可以使用任何客户端模板引擎来解析模板、生成DOM。例如:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var app = new Framework7( {
    preprocess : function( content, url, next ) {
        if ( url === 'user.html' ) {
            // 编译模板
            var template = Template7.compile( content );
            // 链接模板为DOM
            var resultContent = template( {
                title : 'User',
                user : [ 'Alex', 'Meng', 'Cai' ]
            } );
            return resultContent;
        }
    }
} );

可以解析Template7模板:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="navbar">
  <div class="navbar-inner">
    <div class="center">{{title}}</div>
  </div>
</div>
<div class="pages">
  <div data-page="user" class="user">
    <div class="user-content">
      <ul>
        {{#each user}}
        <li>{{this}}</li>
        {{/each}}
      </ul>
    </div>
  </div>
</div>

 为preprocess指定第四个参数next,可以异步的返回链接后的DOM:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var app = new Framework7( {
    preprocess : function( content, url, next ) {
        if ( url === 'user.html' ) {
            // 通过XHR加载用户的JSON数据,用以填充模板
            $$.get( 'user.json', function( data ) {
                // 编译
                var template = Template7.compile( content );
                // 链接
                var resultContent = template( data );
                // 把结果传递给next
                next( resultContent );
            } );
            // 使用next,则不需要返回任何值
        }
    }
} );
preroute:路由拦截 

使用该参数可以阻止F7路由机制的默认行为, 从而加载其他页面、重定向或者执行其他动作。例如当未登录用户请求某个页面时,自动切换到登录页面:

JavaScript
1
2
3
4
5
6
7
8
9
var app = new Framework7( {
    preroute : function( view, options ) {
        if ( !userLoggedIn ) {
            //加载其它页面
            view.router.loadPage( 'auth.html' );
            return false; // 返回false则阻止默认路由行为
        }
    }
} );
视图

在F7中,元素 <div class="views"> 是所有可视化视图(visual view,除了面板、模态窗口之外的视图)的容器,一个F7应用只能有一个views元素。 app.views 属性指向所有视图实例的数组。

元素 <div class="view"> 则代表了一个独立的视图,可以拥有自己的设置、导航和历史,每个视图可以具有自己的导航栏/工具栏布局以及不同的样式。

下面是视图的HTML结构示例:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<body>
    <!-- 面板视图不包括在views内 -->
    <div class="panel panel-left panel-cover">
        <div class="view panel-view">...</div>
    </div>
    <!-- 所有可视化视图,必须作为子元素,这便于我们整个的移动应用——例如打开侧面板时 -->
    <div class="views">
        <!-- view-main为主视图 -->
        <div class="view view-main">
            <!-- 每个视图可以具有自己的导航栏页面、工具栏 -->
            <!-- Navbar-->
            <!-- Pages -->
            <!-- Toolbar-->
        </div>
        <!-- 另外一个视图 -->
        <div class="view another-view">
            <!-- Navbar-->
            <!-- Pages -->
            <!-- Toolbar-->
        </div>
    </div>
    <!-- 弹窗、模态窗口不包括在views内 -->
    <div class="popup">
        <div class="view popup-view">...</div>
    </div>
</body>
主视图

主视图由样式类 view-main  声明,主视图的作用是:

  1. 默认的,所有链接均在主视图中加载页面
  2. PushState哈希导航仅支持主视图
视图初始化

可以使用如下方法添加新的视图:

JavaScript
1
2
3
4
5
/**
* @param container  HTML元素或者CSS选择器,视图的容器元素
* @param parameters 视图的初始化参数
*/
app.addView(container, parameters); //返回一个视图对象
视图初始化参数详解
参数/属性 类型和默认值 说明
dynamicNavbar boolean = false 仅iOS主题。为视图启用动态导航栏
url string = undefined 默认(初始)视图的URL,如果不设置,等同于document的URL
domCache boolean = false 设置为true启用内联页面,这样先前访问的页面均保存在导航链中,不从DOM中移除
linksView string / View instance = undefined 另外一个视图的CSS选择器,或者已经初始化的View实例,默认的,所有链接在此视图中加载页面
该参数可以在运行时动态改变
导航
uniqueHistory boolean

覆盖相应的应用初始化参数

 

uniqueHistoryIgnoreGetParameters boolean = false
allowDuplicateUrls boolean
animatePages boolean
preloadPreviousPage boolean
reloadPages boolean = false 如果启用,视图总是重新载入当前的活动页 
preroute function(view, options)  覆盖相应的应用初始化参数
preprocess function(content, url, next)
  Swipe back(仅iOS主题)
覆盖相应的应用初始化参数
回调(仅iOS主题)   
onSwipeBackMove  function(callbackData) 执行Swipe back操作时,在各阶段执行这些回调,回调入参callbackData为一对象,包含以下属性:
  1. percentage 移动的百分比
  2. activePage 当前活动页对应的HTML元素
  3. previousPage 先前(左边)页面对应的HTML元素
  4. activeNavbar 当前导航栏对应的元素
  5. previousNavbar 先前导航栏对应的元素

    

onSwipeBackBeforeChange function(callbackData)
onSwipeBackAfterChange  function(callbackData)
onSwipeBackBeforeReset function(callbackData) 
onSwipeBackAfterReset  function(callbackData)
视图的属性、方法和事件
属性/方法/事件 说明
params 返回视图初始化参数对象,你可以重写某些参数:
JavaScript
1
mainView.params.linksView = '.another-view'
history 返回视图历史记录的数组,数组的每个元素是已加载页面的URL
contentCache 返回缓存的页面,仅在使用动态生成的内容时,该属性有效
url 返回当前活动页面的URL
pagesContainer 返回作为页面容器的HTML元素
activePage 返回当前页面数据(Page data)对象,该对象代表了当前活动页面
main 如果当前视图是主视图,返回true
router 返回该视图的路由对象
hideNavbar() 隐藏或显示导航栏
showNavbar()
hideToolbar() 隐藏或显示工具栏
showToolbar()
destroy() 销毁已初始化的视图,解除swipe事件监听器,并禁用导航
⚡swipeBackMove 与上面的几个回调对应
⚡swipeBackBeforeChange
⚡swipeBackAfterChange
⚡swipeBackBeforeReset
⚡swipeBackAfterReset
视图默认URL

除了使用初始化参数url,你还可以在视图元素上设置data-url属性,来指定默认URL:

JavaScript
1
<div class="view" data-url="index2.html">
得到当前视图

除了主视图外,我们还可能在popup、popover、面板、Tab中定义视图。某些情况下我们需要得到“当前的”视图——即位于界面最顶层的视图,这是可以调用:

JavaScript
1
app.getCurrentView(index)

如果当前有多个活动视图 ,例如使用拆分视图布局(Split View layout)时,可以传入index来指明需要返回哪个视图。该函数返回视图实例,或者视图的数组。

从DOM访问视图实例

F7为 <div class="view"> 元素添加了特殊的属性 f7View ,它指向元素关联的视图实例:

JavaScript
1
2
var viewsElement = $$('.view-main')[0];
var viewInstance = viewsElement.f7View;

使用app.views属性,可以遍历所有视图:

JavaScript
1
2
3
4
for (var i = 0; i < app.views.length; i ++) {
    var view = app.views[i];
    if (view.main) app.alert('I found main View!')
}
页面

在F7中,页面的概念和传统的Web page类似。下面的代码示意了页面在F7布局里面的位置:

XHTML
1
2
3
4
5
6
7
8
9
10
<div class="views">
    <div class="view view-main">
        <!-- 所有页面的容器元素 -->
        <div class="pages">
            <div class="page" data-page="home"><!-- 页面唯一名称 -->
                <div class="page-content">页面内容,包括所有F7组件,必须声明在这里</div>
            </div>
        </div>
    </div>
</div>

页面必然属于某个视图,页面可以静态的编写在主布局文件(内联)中,也可以动态的从模板中加载进来,甚至通过API动态创建。

和视图类似,在主布局文件(index.html)中,所有页面必须在容器 <div class="pages"> 里面声明,以确保页面能够正常切换。

data-page 属性指定了页面的唯一名称,该属性在页面回调(page callbacks)中非常有用,有助于鉴别哪个页面被加载。

所有F7视觉组件——例如列表、表单——必须存放在 <div class="page-content"> 元素下,只有这样F7才能正确的确定布局、绘制样式和滚动视图。

页面事件

页面导航的关键部分是页面事件,通过页面事件我们可以操控刚刚加载的页面,例如执行JS代码。页面事件的Target(事件源)均为 <div class="page"> 元素,可用的事件如下:

事件 说明
pageBeforeInit 当F7把新页面插入到DOM时触发该事件
pageInit 当F7初始化了新页面中的组件和导航栏后触发该事件
pageReinit 当缓存的页面再次可见时触发该事件,仅适用于内联页面( Inline Pages,即DOM cached pages)
pageBeforeAnimation 当页面初始化完毕后,准备执行动画时,触发该事件
pageAfterAnimation 当页面动画执行完毕后,触发该事件
pageBeforeRemove 在页面从DOM中移除时,触发该事件
监听该事件,以便移除相关的事件处理函数、插件
pageBack 与pageBeforeAnimation类似,但是针对old页面——从屏幕中间向右滑出的那个
pageAfterBack 与pageAfterAnimation类似,但是针对old页面

下面是注册页面事件处理函数的例子:

JavaScript
1
2
3
4
5
6
7
// 针对所有页面,推荐方式
$$( document ).on( 'pageInit', function( e ) {
 
} );
// 针对特定页面
$$( document ).on( 'pageInit', '.page[data-page="about"]', function( e ) {
} );
页面回调

除了通过应用初始化参数指定全局性页面回调以外,还可以调用Framework7对象的相应方法,来针对特定页面回调:

回调 说明
app.onPageBeforeInit 这些函数的签名均为:
JavaScript
1
function(pageName, callback(page));

其中:

  1. pageName:该回调针对的页面的名称,可以用空格分隔多个页面。如果指定*则针对所有页面
  2. callback(page):回调函数,入参是页面数据对象,返回值是一个callbackObject对象

callbackObject对象具有以下方法:

  1. trigger() 手工触发回调函数
  2. remove() 移除回调函数

 

app.onPageInit
app.onPageReinit
app.onPageBeforeAnimation
app.onPageAfterAnimation
app.onPageBeforeRemove
app.onPageBack
app.onPageAfterBack

如果要针对特定页面执行逻辑,页面回调是非常好的选择。页面回调比起页面事件有如下优势:

  1. 回调不是事件,意味着更少的内存使用、更低几率的内存泄漏。同样,你不需要考虑何时解除注册
  2. 代码结构角度来看,更加便利
针对初始页面(Inital Pages)的回调

有时我们需要对初始页面——即内联在index.html中的页面——进行回调,这些页面已经随着应用的初始化而初始化,后续注册的回调无法拦截。这时,我们可以手工初始化应用, 并在之前注册回调:

JavaScript
1
2
3
4
5
6
7
8
9
var app = new Framework7({
  init: false // 禁止自动初始化
});          
// 注册回调
myApp.onPageInit('home', function (page) {
});
myApp.init(); //手工初始化应用
页面数据

 在页面回调(包括应用初始化参数)、页面事件中,可以访问所谓“页面数据(Page data)”对象,该对象包含页面的相关信息:

JavaScript
1
2
3
4
5
6
7
8
//从回调中访问页面数据
app.onPageInit('about', function (page) {
});
// 从事件处理函数中访问页面数据
$$(document).on('pageInit', function (e) {
  var page = e.detail.page;
});

页面数据对象包含以下属性:

属性 说明
name string ,页面名称,对应页面元素的data-page属性
url string ,页面的URL
query object , 页面URL的查询参数部分转换为的对象,例如 index.html?id=10&count=20&color=blue 会转换为:
JavaScript
1
2
3
4
5
{
    id: '10',
    count: '20',
    color: 'blue'
}  
view object , 该页面所属的视图实例
container HTMLElement,页面对应的HTML元素
from string,页面“来自的方向”,对于新加载的页面,该属性值为“right”;对于通过Back按钮加载的历史页面,该属性值为“left”
navbarInnerContainer HTMLElement,与此页面相关的navbar-inner元素,仅用于动态导航栏(Dynamic Navbars)
swipeBack boolean,如果为真,则表示动画由Swipe back触发。仅适用于onPageBefore/AfterAnimation回调和事件
context object,当使用Template7模板时,传递给当前页面的Template7上下文对象
fromPage 上一个活动页的页面数据对象 
导航/路由

F7的页面导航(Navigation )功能相当灵活,你可以通过多种方式处理页面:

  1. Ajax页面(Ajax Pages):从其它文件中加载页面,这是默认行为
  2. 动态页面(Dynamic Pages):可以使用JavaScript API动态的创建并加载页面
  3. 内联页面(Inline Pages):页面的内容可以直接编写在当前HTML里面,不需要额外的加载行为
  4. Template7页面:可以通过Template7模板加载页面。注意这并不是一种独立的页面类型,只是基于T7模板来解析Ajax页面和动态页面
  5. 以上方式可以混合使用

前面我们提到,F7中的视图是应用中独立的可视化部分,可以具有自己的导航和历史。导航路由器(Navigation router)连接到特定视图,作为视图的一部分,负责页面路由、导航工作。

视图导航API
导航方法

F7主要提供了两个方法,用于执行路由:

方法 说明
view.router.load(options) 加载请求的页面到视图中,同时触发动画效果
view.router.back(options) 返回导航历史中的上一个页面,同时触发动画效果
导航参数

上面两个方法的options参数是一个配置对象,支持以下配置参数:

参数 类型 说明
url string 目标页面的URL
content string/HTMLElement/
jQuery Collection/
DOM7 Collection/
HTMLElement[]
路由到动态页面:动态页面的内容 
pageName string 路由到内联页面:内联页面的名称,即data-page属性的值 
template function(Template7已编译模板) 路由到动态页面:需要被链接并加载的Template7模板 
注:以上4个参数必须互斥的使用
context object/array Template7模板需要链接到的上下文对象
contextName string  Template7模板需要链接到的上下文对象,为template7Data中的某个简单数据对象,或者其子对象(点号导航)
query object 额外的查询参数,这些参数以后可以通过页面数据的query属性取回
force boolean 仅用于back()方法,设置为true会忽视既有的历史记录,强制重新加载页面
默认的,当前页来自的那个页面会驻留在DOM中,不消除,因此重新不加载也可以显示之
ignoreCache boolean 如果设置为true,忽略已经缓存的URL,通过XHR强制加载 
animatePages boolean 覆盖对应的视图初始化参数 
reload boolean 如果设置为true,不会把目标页面加载为新页面,而是仅仅替换掉当前页面,并替换视图历史中最新条目
reloadPrevious boolean 与reload类似,但是替换视图历史中上一个页面
pushState boolean 是否把加载的页面压入记录到浏览器的历史中 ,用于哈希导航
导航快捷方法

除了load/back以外,F7还提供了一系列的快捷方法:

快捷方法 说明
加载新页面的快捷方法
view.router.loadPage(url) 从指定URL加载页面到视图,在 <a> 元素上点击通常具有一样的效果
view.loadContent(content) 加载动态页面,content为新的页面的内容,可以是string、HTMLElement、HTMLElement[]、jQuery/Dom7元素集合
重新载入当前页面的快捷方法
view.router.reloadPage(url)

与上面两个快捷方法类似,但是替换掉当前页面(同时修改视图的历史记录),而不是加入新页面

view.router.reloadContent(content)
重新载入上一个页面(如果视图的DOM中存在两个页面)的快捷方法
view.router.reloadPreviousPage(url) 与上面两个快捷方法类似,但是替换的是上一个页面
view.router.reloadPreviousPage(url)
刷新页面的快捷方法
view.router.refreshPage() 相当于使用与当前页面相同的URL执行reload操作
view.router.refreshPreviousPage()
Ajax页面

默认的,Framework7会使用XHR加载所有链接,除非链接元素上标记样式类: <a class="external"> ,或者链接的href为空或者#。应用初始化参数ajaxLinks可以改变此默认行为。因此,点击一个链接元素后,通常F7会:

  1. 发送XHR请求到目标页面
  2. 解析目标页面
  3. 插入到目标页面到当前DOM中
  4. 执行动画以切换(transition)到新页面
单页面的结构

F7的页面解析器很智能,因此供内部使用的页面不需要是完整的HTML(可以不包含html、head、body)、也不需要包含完整的F7布局(不需要views、pages等)。考虑下面的页面:

XHTML
1
2
3
<div class="page" data-page="about">
    Content
</div>

F7的页面解析器仅仅尝试找到XHR加载得到的HTML中的 <div class="page"> 元素,并将其解析为页面。

多页面的结构

F7允许多个视图加载同一个URL,却显示不同的内容。考虑下面的布局:

index.html
XHTML
1
2
3
4
5
6
7
8
9
10
<div class="views">
    <!-- 左视图 -->
    <div class="view view-main left-view">
        <a href="about.html"> About </a>
    </div>
    <!-- 右视图 -->
    <div class="view right-view">
        <a href="about.html"> About </a>
    </div>
</div>

 左右两个视图都包含执行about.html链接。about.html则可以针对不同视图提供差异化内容:

XHTML
1
2
3
4
5
6
<div class="view view-main left-view">
    <div class="page" data-page="about-right">左视图显示的内容</div>
</div>
<div class="view right-view">
    <div class="page" data-page="about-right">右视图显示的内容</div>
</div>

这里的关键之处是,你需要使用view元素包裹page元素。view元素的CSS样式类必须和页面对应的视图一致。 

动态导航栏页面的结构

本节内容仅适用于iOS主题。

动态导航栏元素是独立在页面元素之外的,如果你需要在新页面中指定导航栏内容,可以:

XHTML
1
2
<div class="navbar">导航栏内容</div>
<div class="page" data-page="about">页面内容</div>

在使用多页面时,可以把上面两者包装到同一个view元素中。

返回到原先的页面

可以在链接上特殊样式类back,这样链接被点击后,自动返回上一个页面:

XHTML
1
2
3
<div class="page" data-page="about">
    <a href="index.html" class="back"> Go back to home page </a>
</div>

如果导航历史中存在其他页面,那么href属性被忽略。否则F7通过href载入“前一个”页面。

禁用Swipe back

我们可以为特定页面禁用Swipe back: <div class="page no-swipeback"></div> 。

针对页面启/禁动画

应用程序初始化参数noAnimate可以在全局范围禁用页面切换动画。

我们也可以针对页面启/禁动画:

XHTML
1
2
3
4
5
6
7
8
9
10
<div class="page" data-page="about">
    <!-- 禁用动画 -->
    <a href="about.html" class="no-animation"> Load About page immediately </a>
    <!-- 对返回链接禁用动画 -->
    <a href="index.html" class="back no-animation"> Go back immediately </a>
    <!-- 启用动画 -->
    <a href="about.html" class="with-animation"> Load About page with animation </a>
    <!-- 对返回链接启用动画 -->
    <a href="index.html" class="back with-animation"> Go back with animation </a>
</div>
使用额外导航参数加载页面

把驼峰式大小写的导航参数改为连字符+小写格式,附加 data- 前缀,就可以在 <a> 元素的属性中声明任意额外的导航参数:

XHTML
1
2
3
4
5
6
7
8
<!-- reload=true,ignoreCache=true -->
<a href="about.html" data-reload="true" data-ignore-cache="true"></a>
<!-- force=true -->
<a href="about.html" class="back" data-force="true"></a>
<!-- animatePages=true -->
<a href="about.html" data-animate-pages="false"></a>
<!-- 导航到已有T7模板 -->
<a href="#" data-template="contactsTemplate">Contacts</a>
使用JS加载页面或返回

与HTML链接元素等价的JS加载/返回页面方式是:

JavaScript
1
2
view.router.loadPage('about.html');
view.router.back();
动态页面

F7允许即使的创建并加载动态页面,而不进行额外的XHR请求。动态页面无法通过  <a> 元素完成,必须使用路由API(两个导航方法reload/back或者相应快捷方法)。

关于Ajax页面结构的说明,完全适用于动态页面。

在JS中编写动态页面
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var mainView = new Framework7().addView('.view-main');
// 动态页面的内容,结构必须符合F7规范
var newPageContent = '<div class="page" data-page="my-page">' +
                        '<div class="page-content">' +
                          '<p>Here comes new page</p>' +
                        '</div>' +
                      '</div>';
//加载页面
mainView.router.loadContent(newPageContent);
//另一种方式
mainView.router.load({
  content: newPageContent,
  animatePages: false
});
使用内联模板

在JavaScript中编写HTML很麻烦,我们可以在主布局文件中声明:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
<script type="text/template" id="myPage">
    <div class="navbar">
        <div class="navbar-inner">
            <div class="center">My Page</div>
        </div>
    </div>
    <div class="page" data-page="my-page">
        <div class="page-content">
            <p>Here comes page content</p>
        </div>
    </div>
</script>

然后通过路由API加载: 

JavaScript
1
view.router.loadContent($('#myPage').html());
动态页面的URL 

默认情况下动态页面的URL属于哈希导航,遵循 #content-{{index}} 格式,其中index是导航历史中的页面索引号。该行为可以通过应用初始化参数dynamicPageUrl修改。

内联页面(DOM缓存)

内联页面指直接声明在主布局文件(index.html)中的页面。这种页面不需要额外的Ajax加载动作/动态创建动作,会随着应用的初始化自动加载。

默认情况下,内联页面是禁用的,要为某个视图启用内联页面功能,你需要:

JavaScript
1
2
3
var mainView = myApp.addView('.view-main', {
    domCache: true //启用内联页面功能
});

如果不启用domCache参数,则无法通过 #pageName 导航到其它内联页面。

内联页面DOM结构

必须为非当前活动页面添加额外的cached样式类。最后一个没有标注cached的内联页面会自动显示:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div class="views">
    <div class="view view-main">
        <div class="pages">
            <!-- 内联页面,当前活动页面 -->
            <div class="page" data-page="index">
                <div class="page-content">
                    <p>Home page</p>
                </div>
            </div>
 
            <!-- 已缓存的内联页面 -->
            <div class="page cached" data-page="about">
                <div class="page-content">
                    <p>About page</p>
                </div>
            </div>
 
            <!-- 已缓存的内联页面 -->
            <div class="page cached" data-page="services">
                <div class="page-content">
                    <p>Services page</p>
                </div>
            </div>
        </div>
    </div>
</div>
使用动态导航栏时的内联页面的DOM结构 

本节内容仅适用于iOS主题。

动态导航栏元素是独立在页面元素之外的,要为每个内联页面定制动态导航栏,需要额外的HTML标签:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div class="views">
    <div class="view view-main">
        <!-- 所有内联页面的导航栏设置 -->
        <div class="navbar">
            <!-- 页面1的导航栏,注意data-page属性和对应的页面保持一致 -->
            <div class="navbar-inner" data-page="index"><div class="center">Home</div></div>
            <!-- 页面2的导航栏,注意已缓存的页面的导航栏会加上cached标签 -->
            <div class="navbar-inner cached" data-page="about"><div class="center">About</div></div>
            <!-- 页面3的导航栏 -->
            <div class="navbar-inner cached" data-page="services"><div class="center">Services</div></div>
        </div>
        <!-- 所有内联页面 -->
        <div class="pages navbar-through">
            <!-- 页面1(当前) -->
            <div class="page" data-page="index"><div class="page-content"><p>Home page</p></div></div>
            <!-- 页面2 (已缓存)-->
            <div class="page cached" data-page="about"><div class="page-content"><p>About page</p></div></div>
            <!-- 页面3(已缓存) -->
            <div class="page cached" data-page="services"><div class="page-content"><p>Services page</p></div>
            </div>
        </div>
    </div>
</div>
内联页面的URL

内联页面的URL属于哈希导航,遵循 #{{pageName}} 格式,我们可以使用下面的URL链接到内联页面about:

XHTML
1
<a href="#about">Go to About page</a>
通过JS加载内联页面
JavaScript
1
view.router.load({pageName: 'about'});
跨视图链接

使用JavaScript API,可以很方便的使用view实例加载任何页面。此外,F7还允许点击视图1中的某个链接,而把目标页面加载到视图2中,这就是所谓跨视图链接:

XHTML
1
2
3
4
<!-- 只需要通过data-view属性指定目标视图的CSS选择器,就可以进行跨视图链接 -->
<a href="products.html" data-view=".right-view"> Products </a>
<!-- 右视图 -->
<div class="view right-view">...</div>

对于“back”链接,同样可以使用data-view属性。

样式(Styling)
色彩方案

F7为iOS主题、Material主题预置了多套色彩方案。并分别提供深/浅两套布局主题(Layout Theme)。

要启用色彩方案的支持,必须在F7主样式表文件后附加样式表文件:

XHTML
1
2
3
4
<!-- iOS主题色彩方案样式表 -->
<link rel="stylesheet" href="path/to/framework7.ios.colors.min.css">
<!-- Material主题色彩方案样式表 -->
<link rel="stylesheet" href="path/to/framework7.material.colors.min.css">
色彩方案列表

 f7-colors

应用色彩方案

可以在多个元素上应用色彩方案,只需要添加相应的 theme-* 样式类:

XHTML
1
2
3
4
5
<body class="theme-red"></body> <!-- 全局 -->
<div class="page theme-green"></div> <!-- 页面 -->
<div class="list-block theme-pink"></div> <!-- 列表 -->
<div class="navbar theme-orange"></div> <!-- 导航栏 -->
<div class="buttons-row theme-yellow"></div> <!-- 按钮 -->
应用布局主题 

可以指定应用是深色风格还是浅色风格:

XHTML
1
2
3
<body class="layout-dark"></body>
<div class="page layout-white"></div>
<div class="list-block layout-dark"></div>
辅助样式类

F7提供了若干与色彩方案相关的辅助样式类:

  1. color-*:指定元素的文本颜色
  2. bg-*:指定元素的背景颜色
  3. border-*:指定元素的边框颜色 

注意,不支持在指定色彩方案的容器内指定辅助样式类:

XHTML
1
2
3
<div class="theme-red">
    <a href="#" class="color-blue">链接将是红色的,而不是蓝色</a>
</div>
边框(细线)

 从F7的1.x版本开始,支持使用 :after 和 :before 伪元素代替CSS边框。这样就可以支持iOS视网膜屏幕0.5px、0.33px(iPhone 6P)的细线。

伪元素使用规则很简单:

  1. :after对应bottom、right细线
  2. :before对应left、top细线
使用示例
CSS
1
2
3
4
5
6
7
8
9
10
11
/* 修改导航栏底部细线为红色 */
.navbar:after {
  background-color: red;
}
/* 移除导航栏、工具栏的细线 */
.navbar:after {
  display:none;
}
.toolbar:before {
  display:none;
}
no-border类 

该样式类也可以用于移除细线,但是目前不支持导航栏、工具栏、卡片(包括头/尾)。

快速点击库

本章介绍的功能是F7内置的快速点击库的一部分,必须在应用初始化参数中启用快速点击才可以使用。

活动状态

F7使用所谓活动状态(active state) 来高亮显示被触碰的按钮与链接。

类似于CSS选择器 :active ,当你触碰元素并持续一小段时间后,F7会自动添加 active-state 样式类。通过定制CSS,可以为被触碰的元素添加额外样式:

CSS
1
2
3
4
5
6
7
8
/* 一般状态 */
.my-button {
    color: red;
}
/* 活动状态(触碰) */
.my-button.active-state {
    color: blue;
}  
长按事件

 F7支持触碰并保持(Tap Hold)事件,亦即长按(Long Tap)事件。此功能默认禁用,可以设置应用初始化参数tapHold、tapHoldDelay、tapHoldPreventClicks以启用并定制。

你可能需要禁用移动浏览器默认的长按动作,向目标元素添加额外样式规则:

CSS
1
2
3
-moz-user-select: none;        
-webkit-user-select: none;        
user-select: none;

 你可以监听 taphold 事件,指定长按时需要执行的动作。

波纹效果

仅用于Material主题,可以在触碰点生成一个扩散的涟漪效果。 此效果默认全局范围内启用,设置应用初始化参数 materialRipple:false 则可禁用。哪些元素启用此效果,则由应用初始化参数 materialRippleElements 指定。

要为某个元素启用波纹效果,可以:

XHTML
1
<a href="#" class="my-link ripple">Link With Ripple Effect</a>

要为某个元素禁用波纹效果,可以:

XHTML
1
<a href="#" class="button no-ripple">Button Without Ripple Effect</a>
指定波纹颜色

可以使用内置的 ripple-* 样式类,或者自定义:

CSS
1
2
3
.button .ripple-wave {
    background-color: #ff0000;
}  
实用工具
设备API

F7内置了一个设备检测库,在应用初始化后,你可以访问 app.device 对象。该对象包含若干与设备相关的有用信息:

属性 类型 说明
os string 操作系统类型, 可以是android、ios。对于其它任何系统,均为undefined
osVersion string 操作系统版本字符串
android boolean 是否为安卓设备
ios boolean 是否为iOS设备
ipad boolean 是否为iPad
iphone boolean 是否为iPhone
pixelRatio number 像素比率,在高分屏中,多少物理像素对应一个逻辑像素
webView boolean 如果应用程序运行在UIWebView中,则为true。使用Phonegap时,此属性为true
minimalUi boolean minimal-ui模式是否处于启用状态
statusBar boolean 仅iOS,当应用在全屏模式下运行,并且需要状态栏Overlay时为true

要在应用初始化之前使用设备API,可以:

JavaScript
1
2
3
4
var device = Framework7.prototype.device;
if (device.iphone) {
    console.log('this is iPhone')
}
额外的样式类 

设备API会自动为html元素添加额外的样式类,便于开发者针对不同设备定制UI: 

XHTML
1
2
3
4
5
6
7
8
<!-- 为iOS 7.1设备添加的额外样式类 -->
<html class="ios ios-7 ios-7-1 ios-gt-6 pixel-ratio-1">
<!-- 为iOS 7.1视网膜屏、运行全屏应用程序时添加的样式类 -->
<html class="ios ios-7 ios-7-1 ios-gt-6 retina pixel-ratio-2 with-statusbar-overlay">
<!-- 为iOS 8.0的iPhone 6 Plus添加的样式类 -->
<html class="ios ios-8 ios-8-0 ios-gt-6 ios-gt-7 retina pixel-ratio-3 with-statusbar-overlay">
<!-- 为 Android 4.4 设备添加的额外样式类 -->
<html class="android android-4 android-4-4">
← 在Ubuntu上安装百度云客户端
Mocha学习笔记 →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • Framework7知识集锦
  • 基于AngularJS开发Web应用
  • HTTP知识集锦
  • HTML5视频监控技术预研
  • Sencha Cmd学习笔记

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • Bazel学习笔记 37 people like this
  • PhoneGap学习笔记 32 people like this
  • NaCl学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2