上一篇基本介绍了History API,这篇咱们可以同jquery插件来简单封装一个pjax来使用和体验下。

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
(function($) {
//配置参数
var defaults = {
};
//public方法
var methods = null;
//private方法
var _methods = null;
methods = {
//需要暴漏给外部的方法写在这里
init : function(options) {
defaults = $.extend(defaults, options);
_methods._initEvent();
},
};
_methods = {
//私有方法写在这里
};
$.pjax = function() {
var method = arguments[0];
if (methods[method]) {
method = methods[method];
arguments = Array.prototype.slice.call(arguments, 1);
} else if (typeof (method) == 'object' || !method) {
method = methods.init;
} else {
$.error('Method ' + method + ' does not exist on jQuery.pjax');
return this;
}
return method.apply(this, arguments);
};
})(jQuery);



基本的脚手架完成,下一步咱们直接说说我们需要的参数。

Pjax 参数定义

参数的话,咱们可以方法 defaults 这个Object中。
下面讨论下咱们需要初始化pajx的参数:

1.mainContainer -> 主容器,也就是需要把异步加载的HTML内容加载到哪个DOM中,这里一般都是一个DIV吧。

2.defaultLoad->默认初始化哪个页面,初始化成功的时候,咱们需要一个默认加载页面。还有就是如果在url找不到的时候这里也可以起到一个默认路由的作用,直接跳到默认的页。

3.suffix -> 后缀,其实这个参数是方便书写,如果项目中的页面都是html的话,这个参数可以写成’html’ 然后在后续的操作跳转等操作的时候就不用写’xxx.html’了,直接写’xxx’即可

代码片段:

1
2
3
4
5
var defaults = {
mainContainer:"mainContainer",
suffix:"html",
defaultLoad:"index",
};



后续还可以添加更丰富的功能,比如缓存机制,自定义跳转动画效果等功能,咱们现在就把基础的pjax现玩明白再说。

Pjax 方法定义和实现DOM Attr跳转

关于页面的跳转其实就是主要的方法:
1.load -> 跳转到指定的页面,还可以传各种参数(还可以允许是否可回退)。

2.back -> 回退到之前的页面。

这里还需要DOM 属性来支持咱们的pjax,举个栗子:

1
<a>跳转</a>

这种代码需要直接支持pjax跳转怎么办?

这样写,然后看下后续的JS代码就知道了:

1
<a pa-href="demo2" >跳转到demo2.html</a>

下面代码是暴漏给外部的方法
代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
methods = {
//初始化调用
init : function(options) {
//拼接参数
defaults = $.extend(defaults, options);
//初始化事件
_methods._initEvent();
},
//加载界面,
//url ->加载的url地址
//param -> 需要传到下个页面的参数,JSON格式
//isNotBak ->如果为true,则没有回退功能
load :function(url,param,isNotBack){
_methods._load(url,param,!isNotBack);
},
//回退到上一个页面
back :function(){
_methods._back();
}
};



下面介绍下私有的方法
代码片段:

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
_methods ={
//初始化事件并调用基本事件
_initEvent:function(){
//实现DOM Attr方式调用
$('body').delegate('*[pa-href]', 'click', function(event) {
var $this=$(this);
var href = $this.attr("pa-href");
if($this.attr("pa-noBack")!=undefined && $this.attr("pa-noBack") ==''){
_methods._load(href);
}else{
_methods._load(href,{},true);
}
});
//这里判断浏览器是否可用
if (history.pushState) {
//默认调用一次,来加载默认界面
_methods._changeHistory(true);
//监听History改变
window.addEventListener("popstate", function(e){
_methods._changeHistory(false);
});
}
},
//触发History改变事件调用
//refresh -> 若为true,则为首次刷新界面用,一般用于第一次调用时传true
_changeHistory:function(refresh){
//判断paHref参数如果在url有值则代表需要跳转到指定页面.
var href=_methods._getParam('paHref');
if(href){
_methods._load(href,{},refresh);
}else{
_methods._load(defaults.defaultLoad);
}
},
//获取URL中的某些参数
_getParam:function(name){
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null)
return unescape(r[2]);
return null;
},
//核心方法,加载指定URL内容到主容器中
//方法就不介绍了,上面已经介绍了
_load:function(url,param,isBack){
var main=$("#"+defaults.mainContainer);
//滚动到顶部
window.scrollTo(0,0);
//动画效果
//动画离开
main.fadeOut(200, function(){
//加载URL的内容到容器中
main.load(url+"."+defaults.suffix,{},function(html){
//动画进入
main.fadeIn(200);
//处理title
var matches = html.match(/<title>(.*?)<\/title>/);
if (matches) {
title = matches[1];
document.title = title;
}
})
});
//获取URL的URL部分
var href=location.href.split("?")[0];
//判断是否可以回退
if(isBack){
//把需要跳转的URL写入URL中
href+="?paHref=" + url;
//拼接请求参数
if(param && !$.isEmptyObject(param)){
href+="&"+$.param(param);
}else{
var p=window.location.search;
if(p.indexOf('&')!= -1){
href+=p.substring(p.indexOf('&'))
}
}
//直接push到History,并记录
history.pushState({isBack:isBack}, document.title, href);
}
},
//回退
_back:function(){
history.back();
}
}

下一篇介绍怎么来实际使用插件来工作。

git项目地址

用右眼看世界