jQuery Mobile在SPA模式下的多页面跳转原理及实现案例
文章目录
- jQuery Mobile在SPA模式下的多页面跳转原理及实现案例
- 前言
- 一、SPA的实现原理和代码分析
- 1.实现原理说明
- (1)index.html
- (2)index.js
- (3)page2.html
- (4)page2.js
- 2.代码分析
- 二、特别说明
前言
jQuery Mobile提供了采用SPA(Single Page Application)方式的多页面开发,特别适合于移动跨端开发中提升多页面应用的性能。其中,在官方文档提到了changePage、loadPage的方式,也给出了采用< a href>标签的方式,并且在官方文档中只给出了以内联方式的多页面切换(即各个页面写在同一个html文件中,用< div data-role=“page” id=“pagex”>区分不同页面,其中的x代表了page1、page2…),但对于一个包含较多页面的应用,会导致html文件过于复杂和超长,带来维护困难和可读性差的问题。
那么在jQuery Mobile中SPA下多页面的不同调用方式有什么区别?对于单独保存为不同的html页面又该如何调用呢?
本文详细分析和描述了jQuery Mobile中SPA多页面调用外部和内联页面的原理,并给出代码分析。
一、SPA的实现原理和代码分析
1.实现原理说明
在示例中是基于jQuery Mobile开发的cordova App。
主入口index.html中采用不同方式调用了page2.html或内联页面pagetwo。代码如下:
(1)index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/index.css">
<link rel="stylesheet" href="lib/jquery.mobile-1.4.5.min.css">
<script src="lib/jquery-2.2.4.min.js"></script>
<script src="js/index.js"></script>
<!--index.js必须在jqmobile调用前加载,否则mobileinit不会被捕获,导致init函数不执行-->
<script src="lib/jquery.mobile-1.4.5.min.js"></script>
<title>Multi Page Change Demo</title>
</head>
<body>
<div data-role="page" id="pageone">
<div data-role="header">
<h2>第一页</h2>
</div>
<div data-role="main" class="ui-content">
<button id="page2Btn">changePage按钮跳转page2</button>
<a href="page2.html" data-role="button" data-ajax="true" data-transition="slide">ajax锚跳转page2</a>
<a href="#pagetwo" class="ui-shadow" data-transition="slide" data-role="button">内联跳转page2</a>
</div>
<div data-role="footer">
<h3>版权所有©W</h3>
</div>
</div>
<!--以下为内联页面-->
<div data-role="page" id="pagetwo">
<div data-role="header">
<h2>第二页</h2>
</div>
<div data-role="main" class="ui-content">
<a href="#pageone" data-transition="flip">跳转到第一个页面</a>
</div>
<div data-role="footer">
<h3>版权所有©W</h3>
</div>
</div>
<script src="cordova.js"></script>
<script src="js/index.js"></script>
</body>
</html>
(2)index.js
var deviceReadyDeferred = $.Deferred();
var jqmReadyDeferred = $.Deferred();
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
deviceReadyDeferred.resolve();
}
$(document).on("mobileinit",function(){
jqmReadyDeferred.resolve();
});
function init(){
$(document).on("touchend","#page2Btn",function(e){
alert("in index.js click page2Btn,开始跳转外部page2.html");
// $.mobile.changePage("page2.html");//成功
// $.mobile.loadPage("page2.html");//该方式不成功
//该方式可访问内联页面
// $.mobile.changePage("#pagetwo",{
// transition:"pop",
// reverse:true
// });
//该方式也成功
$.mobile.pageContainer.pagecontainer("change","page2.html",{
changeHash:false
});
});
$(document).on("touchend","#page1Btn",function(e){
alert("in index.js click page1Btn which in page2.html,开始跳转外部index.html")
// $.mobile.changePage("index.html");
$.mobile.changePage("index.html",{
transition:"pop",
reverse:true
});
});
}
(3)page2.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Page 2</title>
<link rel="stylesheet" href="lib/jquery.mobile-1.4.5.min.css">
<script src="lib/jquery-2.2.4.min.js"></script>
<script src="lib/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
<!--ajax方式只会更新div data-role="page"其中的部分-->
<div data-role="page" id="page2">
<div data-role="header">
<h1>Page 2</h1>
</div>
<div data-role="main" class="ui-content">
<p>This is Page 2.</p>
<button id="page1Btn">回到第一个页面</button>
<a href="index.html" data-role="button" data-ajax="true" data-transition="slide" data-direction="reverse">ajax锚方式返回</a>
</div>
<div data-role="footer">
<h4>Footer</h4>
</div>
</div>
在div外面的部分将不会被Ajax方式加载,因此该部分文字和page2.js不会被执行
<script src="js/page2.js"></script>
</body>
</html>
(4)page2.js
在运行中,page2.js不会被执行
$(document).on("touchend","#page1Btn",function(e){
alert("in page2.js click page1Btn,changePage跳转index.html");
$.mobile.changePage("index.html");
// $.mobile.changePage("index.html",{
// transition:"pop",
// reverse:true
// });
});
2.代码分析
运行结果如图:
确定后,则跳转到page2.html, 如图,再点击"回到第一个页面",则又回页面index.html
点击其中的"AJAX锚跳转PAGE2”和“AJA X锚方式返回",也具有同样的效果,只是实现代码采用了< a href>方式;
而”内联跳转PAGE2“则是显示的index.html中的pagetwo页面。
二、特别说明
在index.js中用了Deferred延迟对象来实现挂起进程,直到用resolve()可以继续执行。
在其中需要判断deviceready和mobileinit两个事件都就绪后,才开始执行init函数的内容。
因此,要特别注意两个事件的触发机制。
- jQuery Mobile的mobileinit事件,会在
<script src="lib/jquery.mobile-1.4.5.min.js"></script>
加载后马上触发,甚至早于 jQuery 的 document.ready 事件,因此,自己开发的绑定侦听事件的index.js需要在加载 jQuery Mobile之前,否则会由于错过mobileinit而导致侦听不执行!因此,应按如下顺序加载 jQuery Mobile:
<link rel="stylesheet" href="jquery.mobile-XXX.css">
<script src="jquery-XXX.js"></script>
<script src="index.js"></script><!--自己的js文件-->
<script src="jquery.mobile-XXX.js"></script>