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还包括更多的特性:
- 原生的滚动效果(Native Scrolling)
- 不依赖任何第三方框架
- 高性能的,基于CSS的动画
- 支持缓存、历史、预加载(Preloading)
- 支持无限制的多视图,不需要任何JavaScript代码即可控制视图
- 简洁的JavaScript API
- DOM7:内置的DOM操控库,风格类似于jQuery
该页面声明了应用程序基本的布局:
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> |
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> |
初始化应用和视图:
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 } ); |
如果要针对某个页面的添加脚本,可以:
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页面 } ); |
在DOM操控方面,F7没有使用第三方库,而是自己实现了一个称为DOM7的组件。该组件的接口风格类似于jQuery:
1 2 3 4 |
var $$ = Dom7; $$( '.something' ).on( 'click', function( e ) { $$( this ).addClass( 'hello' ).attr( 'title', 'world' ).insertAfter( '.something-else' ); } ); |
下面的方法均属于元素集——即 Dom7() 调用的返回值:
方法 | 说明 | ||
addClass() | 添加样式类:
|
||
removeClass() | 移除样式类:
|
||
hasClass() | 判断是否存在至少一个匹配元素具有样式类:
|
||
toggleClass() | 如果匹配元素上有指定样式类,移除;反之则添加:
|
||
prop() | 读取或者写入Property:
|
||
attr() | 读取或者写入Attribute,Attribute与Property类似,但是前者相当于直接操作XML的属性节点:
|
||
val() | 得到第一个匹配元素的值,或者设置所有匹配元素的值:
|
||
data() | 读取第一个匹配元素上存储的(任意)数据,或者写入所有匹配元素的数据:
|
||
dataset() | 返回元素上定义的数据集(即data- 属性)为简单对象:
|
||
transform() | 添加CSS转换属性:
|
||
transition() | 设置CSS变换持续时间:
|
||
on() | 注册事件处理器:
|
||
once() | 注册只执行一次的事件处理器 | ||
off() | 移除事件处理器:
|
||
trigger() | 触发匹配元素上指定事件,并执行所有已注册的事件处理器:
|
||
transitionEnd() | 添加CSS变换结束处理器:
|
||
animationEnd() | 添加动画效果结束处理器:
|
||
width() | 得到第一个匹配元素的实际宽度 | ||
outerWidth() | 得到第一个匹配元素的宽度,包括补白和边框,如果入参true,则还包括margin | ||
height() | 得到第一个匹配元素的实际高度 | ||
outerHeight() | 得到第一个匹配元素的高度,包括补白和边框,如果入参true,则还包括marg | ||
offset() | 得到第一个匹配元素相对于document的偏移量:
|
||
hide() | 设置 display:none 以隐藏所有匹配元素 | ||
show() | 设置 display:block 以显示所有匹配元素 | ||
css() | 获取或者设置CSS属性:
|
||
scrollTop() | 滚动元素 | ||
scrollLeft() | |||
scrollTo() | |||
add() | 添加元素到既有的Dom7元素集中:
|
||
each() | 迭代元素集合,执行回调函数 | ||
html() | 得到第一个元素的HTML内容,或者设置所有匹配元素的HTML内容 | ||
text() | 得到第一个元素的文本内容,或者设置所有匹配元素的文本内容 | ||
is() | 判断当前元素集是否匹配指定的CSS选择器、HTML元素或者Dom7元素集合:
|
||
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) | 过滤当前元素集:
|
||
remove() | 从DOM树中移除当前元素集 |
下表是一系列事件处理的快捷方式,它们都属于元素集对象。调用 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上:
函数 | 说明 | ||
each() | 遍历“可迭代对象”,函数签名:
Dom7.each(object/array, callback); 示例:
|
||
parseUrlQuery() | 解析URL并提取请求参数:
|
||
isArray() | 判断一个对象是否为数组 | ||
unique() | 返回数组的一个去重副本 | ||
serializeObject() | 以URL请求参数的形式串行化一个简单对象(PO) | ||
toCamelCase() | 从短横线连接风格(web-app)转换为驼峰式大小写(webApp) | ||
dataset() | 将元素(CSS选择器)中的data-*属性转换为简单对象(PO) |
我们可以调用 $$.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状态码对应的回调:
|
为了简化常用类型的XHR请求的发送,Dom7提供以下快捷函数:
函数 | 说明 |
Dom7.get() | 这三个函数都接受三个入参:
|
Dom7.post() | |
Dom7.getJSON() |
下表列出Dom7扩展的,全局的Ajax监听事件。这些事件都从 document 对象上发出:
事件 | 说明 |
ajaxStart | 在XHR请求发送前触发,可以全局性的修改请求,例如添加请求头 |
ajaxError | 当任何XHR请求处理失败时触发 |
ajaxSuccess | 当任何XHR请求处理成功时触发 |
ajaxComplete | 当任何XHR请求处理完毕后触发,该事件在ajaxError/ajaxSuccess之后触发 |
使用上述事件的例子如下:
1 2 3 4 |
$$(document).on('ajaxComplete', function (e) { var xhr = e.detail.xhr; console.log('request performed'); }); |
F7框架的文档中多次提到布局(Layout)这一个词,在这里布局是指应用程序或者F7组件的HTML结构。
开发F7应用的第一步,就是创建包含应用程序骨架的index.html文件,此文件包含了应用程序的基本布局。
iOS的基础布局样例可以参考前面的章节,Android Material风格的布局,与iOS稍微不同:
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应用的实例:
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选择器 | ||
materialPreloaderHtml | string =
|
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 =
|
智能选择页面后退按钮的HTML模板 | ||
smartSelectPopupCloseTemplate | string =
|
智能选择弹框关闭按钮的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); 其中:
这些参数与对应的页面回调具有类似的功能 |
当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,我们可以使用任何客户端模板引擎来解析模板、生成DOM。例如:
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模板:
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:
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,则不需要返回任何值 } } } ); |
使用该参数可以阻止F7路由机制的默认行为, 从而加载其他页面、重定向或者执行其他动作。例如当未登录用户请求某个页面时,自动切换到登录页面:
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结构示例:
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 声明,主视图的作用是:
- 默认的,所有链接均在主视图中加载页面
- PushState哈希导航仅支持主视图
可以使用如下方法添加新的视图:
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为一对象,包含以下属性:
|
onSwipeBackBeforeChange | function(callbackData) | |
onSwipeBackAfterChange | function(callbackData) | |
onSwipeBackBeforeReset | function(callbackData) | |
onSwipeBackAfterReset | function(callbackData) |
属性/方法/事件 | 说明 | ||
params | 返回视图初始化参数对象,你可以重写某些参数:
|
||
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,你还可以在视图元素上设置data-url属性,来指定默认URL:
1 |
<div class="view" data-url="index2.html"> |
除了主视图外,我们还可能在popup、popover、面板、Tab中定义视图。某些情况下我们需要得到“当前的”视图——即位于界面最顶层的视图,这是可以调用:
1 |
app.getCurrentView(index) |
如果当前有多个活动视图 ,例如使用拆分视图布局(Split View layout)时,可以传入index来指明需要返回哪个视图。该函数返回视图实例,或者视图的数组。
F7为 <div class="view"> 元素添加了特殊的属性 f7View ,它指向元素关联的视图实例:
1 2 |
var viewsElement = $$('.view-main')[0]; var viewInstance = viewsElement.f7View; |
使用app.views属性,可以遍历所有视图:
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布局里面的位置:
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页面 |
下面是注册页面事件处理函数的例子:
1 2 3 4 5 6 7 |
// 针对所有页面,推荐方式 $$( document ).on( 'pageInit', function( e ) { } ); // 针对特定页面 $$( document ).on( 'pageInit', '.page[data-page="about"]', function( e ) { } ); |
除了通过应用初始化参数指定全局性页面回调以外,还可以调用Framework7对象的相应方法,来针对特定页面回调:
回调 | 说明 | ||
app.onPageBeforeInit | 这些函数的签名均为:
其中:
callbackObject对象具有以下方法:
|
||
app.onPageInit | |||
app.onPageReinit | |||
app.onPageBeforeAnimation | |||
app.onPageAfterAnimation | |||
app.onPageBeforeRemove | |||
app.onPageBack | |||
app.onPageAfterBack |
如果要针对特定页面执行逻辑,页面回调是非常好的选择。页面回调比起页面事件有如下优势:
- 回调不是事件,意味着更少的内存使用、更低几率的内存泄漏。同样,你不需要考虑何时解除注册
- 代码结构角度来看,更加便利
有时我们需要对初始页面——即内联在index.html中的页面——进行回调,这些页面已经随着应用的初始化而初始化,后续注册的回调无法拦截。这时,我们可以手工初始化应用, 并在之前注册回调:
1 2 3 4 5 6 7 8 9 |
var app = new Framework7({ init: false // 禁止自动初始化 }); // 注册回调 myApp.onPageInit('home', function (page) { }); myApp.init(); //手工初始化应用 |
在页面回调(包括应用初始化参数)、页面事件中,可以访问所谓“页面数据(Page data)”对象,该对象包含页面的相关信息:
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 会转换为:
|
||
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 )功能相当灵活,你可以通过多种方式处理页面:
- Ajax页面(Ajax Pages):从其它文件中加载页面,这是默认行为
- 动态页面(Dynamic Pages):可以使用JavaScript API动态的创建并加载页面
- 内联页面(Inline Pages):页面的内容可以直接编写在当前HTML里面,不需要额外的加载行为
- Template7页面:可以通过Template7模板加载页面。注意这并不是一种独立的页面类型,只是基于T7模板来解析Ajax页面和动态页面
- 以上方式可以混合使用
前面我们提到,F7中的视图是应用中独立的可视化部分,可以具有自己的导航和历史。导航路由器(Navigation router)连接到特定视图,作为视图的一部分,负责页面路由、导航工作。
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() |
默认的,Framework7会使用XHR加载所有链接,除非链接元素上标记样式类: <a class="external"> ,或者链接的href为空或者#。应用初始化参数ajaxLinks可以改变此默认行为。因此,点击一个链接元素后,通常F7会:
- 发送XHR请求到目标页面
- 解析目标页面
- 插入到目标页面到当前DOM中
- 执行动画以切换(transition)到新页面
F7的页面解析器很智能,因此供内部使用的页面不需要是完整的HTML(可以不包含html、head、body)、也不需要包含完整的F7布局(不需要views、pages等)。考虑下面的页面:
1 2 3 |
<div class="page" data-page="about"> Content </div> |
F7的页面解析器仅仅尝试找到XHR加载得到的HTML中的 <div class="page"> 元素,并将其解析为页面。
F7允许多个视图加载同一个URL,却显示不同的内容。考虑下面的布局:
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则可以针对不同视图提供差异化内容:
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主题。
动态导航栏元素是独立在页面元素之外的,如果你需要在新页面中指定导航栏内容,可以:
1 2 |
<div class="navbar">导航栏内容</div> <div class="page" data-page="about">页面内容</div> |
在使用多页面时,可以把上面两者包装到同一个view元素中。
可以在链接上特殊样式类back,这样链接被点击后,自动返回上一个页面:
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: <div class="page no-swipeback"></div> 。
应用程序初始化参数noAnimate可以在全局范围禁用页面切换动画。
我们也可以针对页面启/禁动画:
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> 元素的属性中声明任意额外的导航参数:
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> |
与HTML链接元素等价的JS加载/返回页面方式是:
1 2 |
view.router.loadPage('about.html'); view.router.back(); |
F7允许即使的创建并加载动态页面,而不进行额外的XHR请求。动态页面无法通过 <a> 元素完成,必须使用路由API(两个导航方法reload/back或者相应快捷方法)。
关于Ajax页面结构的说明,完全适用于动态页面。
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很麻烦,我们可以在主布局文件中声明:
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加载:
1 |
view.router.loadContent($('#myPage').html()); |
默认情况下动态页面的URL属于哈希导航,遵循 #content-{{index}} 格式,其中index是导航历史中的页面索引号。该行为可以通过应用初始化参数dynamicPageUrl修改。
内联页面指直接声明在主布局文件(index.html)中的页面。这种页面不需要额外的Ajax加载动作/动态创建动作,会随着应用的初始化自动加载。
默认情况下,内联页面是禁用的,要为某个视图启用内联页面功能,你需要:
1 2 3 |
var mainView = myApp.addView('.view-main', { domCache: true //启用内联页面功能 }); |
如果不启用domCache参数,则无法通过 #pageName 导航到其它内联页面。
必须为非当前活动页面添加额外的cached样式类。最后一个没有标注cached的内联页面会自动显示:
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> |
本节内容仅适用于iOS主题。
动态导航栏元素是独立在页面元素之外的,要为每个内联页面定制动态导航栏,需要额外的HTML标签:
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属于哈希导航,遵循 #{{pageName}} 格式,我们可以使用下面的URL链接到内联页面about:
1 |
<a href="#about">Go to About page</a> |
1 |
view.router.load({pageName: 'about'}); |
使用JavaScript API,可以很方便的使用view实例加载任何页面。此外,F7还允许点击视图1中的某个链接,而把目标页面加载到视图2中,这就是所谓跨视图链接:
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属性。
F7为iOS主题、Material主题预置了多套色彩方案。并分别提供深/浅两套布局主题(Layout Theme)。
要启用色彩方案的支持,必须在F7主样式表文件后附加样式表文件:
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"> |
可以在多个元素上应用色彩方案,只需要添加相应的 theme-* 样式类:
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> <!-- 按钮 --> |
可以指定应用是深色风格还是浅色风格:
1 2 3 |
<body class="layout-dark"></body> <div class="page layout-white"></div> <div class="list-block layout-dark"></div> |
F7提供了若干与色彩方案相关的辅助样式类:
- color-*:指定元素的文本颜色
- bg-*:指定元素的背景颜色
- border-*:指定元素的边框颜色
注意,不支持在指定色彩方案的容器内指定辅助样式类:
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)的细线。
伪元素使用规则很简单:
- :after对应bottom、right细线
- :before对应left、top细线
1 2 3 4 5 6 7 8 9 10 11 |
/* 修改导航栏底部细线为红色 */ .navbar:after { background-color: red; } /* 移除导航栏、工具栏的细线 */ .navbar:after { display:none; } .toolbar:before { display:none; } |
该样式类也可以用于移除细线,但是目前不支持导航栏、工具栏、卡片(包括头/尾)。
本章介绍的功能是F7内置的快速点击库的一部分,必须在应用初始化参数中启用快速点击才可以使用。
F7使用所谓活动状态(active state) 来高亮显示被触碰的按钮与链接。
类似于CSS选择器 :active ,当你触碰元素并持续一小段时间后,F7会自动添加 active-state 样式类。通过定制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以启用并定制。
你可能需要禁用移动浏览器默认的长按动作,向目标元素添加额外样式规则:
1 2 3 |
-moz-user-select: none; -webkit-user-select: none; user-select: none; |
你可以监听 taphold 事件,指定长按时需要执行的动作。
仅用于Material主题,可以在触碰点生成一个扩散的涟漪效果。 此效果默认全局范围内启用,设置应用初始化参数 materialRipple:false 则可禁用。哪些元素启用此效果,则由应用初始化参数 materialRippleElements 指定。
要为某个元素启用波纹效果,可以:
1 |
<a href="#" class="my-link ripple">Link With Ripple Effect</a> |
要为某个元素禁用波纹效果,可以:
1 |
<a href="#" class="button no-ripple">Button Without Ripple Effect</a> |
可以使用内置的 ripple-* 样式类,或者自定义:
1 2 3 |
.button .ripple-wave { background-color: #ff0000; } |
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,可以:
1 2 3 4 |
var device = Framework7.prototype.device; if (device.iphone) { console.log('this is iPhone') } |
设备API会自动为html元素添加额外的样式类,便于开发者针对不同设备定制UI:
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"> |
Leave a Reply