history之学习联想

1.history.back()
通过这个方法我们可以像点击浏览器的返回按钮,实现页面的返回。
2.history.forward()
通过这个方法我们可以如果点击浏览器的前进按钮。
3.history.go()
跳转到session历史中的一个页面。

1
2
3
history.go(1); //向前一页
history.go(-1); //向后一页
//通过传入参数可以前进退后多页(session中的历史页面)

4.history.pushState()
pushState可以传入三个参数,第一个参数为state对象,第二个参数为标题(试了好像不管用),第三个参数为跳转的url。

state可以让我们存储一些json对象的值,我们可以在history.state中获取到值。
url可以传入一个相对路径,会在当前的路径下加上传入的url:

1
2
3
//路径为http://localhost:3000
history.pushState({name: 'moneyinto'}, '页面标题', '#another');
//之后的路径为http://localhost:3000/#another

5.history.replaceState()
replaceState和pushState用法很像,只是replaceState是修改当前的history,而pushState是创建新的history。

6.window.onpopstate
监听浏览器的返回或history.back()

1
2
3
window.addEventListener("popstate", function() {
//返回后执行的代码
});


关于popstate和pushstate我们来联想一下angular的应用,是不是他的单页应用就是通过这样实现的呢?这个吗,我们可以自己试着来实现一个简单的单页应用。不过问题还存在很多

######simpleSinglePageApp

######demo
我们有个首页index.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>simpleSinglePageApp</title>
<link rel="stylesheet" href="lib/singlePage/singlePage.css" />
<link rel="stylesheet" href="css/style.css" />
<script src="router.js"></script>
<script src="lib/singlePage/singlePage.js"></script>
</head>
<body>

</body>
</html>

我们也建个router.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var router = {
home: {
template: 'tpl/home.html',
controller: 'js/home.js'
},

detail: {
template: 'tpl/detail.html',
controller: 'js/detail.js'
},

about: {
template: 'tpl/about.html',
controller: 'js/about.js'
}
};

var routerHome = router.home;

我们创建各自tpl和js。

  • home.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <div class="list">
    <div class="item">
    我是第一条
    </div>

    <div class="item">
    我是第二条
    </div>

    <div class="item">
    我是第三条
    </div>

    <div class="item">
    我是第四条
    </div>

    <div class="item">
    我是第五条
    </div>
    </div>
  • home.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    (function () {
    var items = document.getElementsByClassName('item');
    items[0].onclick = function () {
    single.go('detail',{id: 1});
    };

    items[1].onclick = function () {
    single.go('detail',{id: 2});
    };

    items[2].onclick = function () {
    single.go('detail',{id: 3});
    };

    items[3].onclick = function () {
    single.go('detail',{id: 4});
    };

    items[4].onclick = function () {
    single.go('detail',{id: 5});
    };
    })();
  • detail.html

    1
    2
    3
    <div>
    我是第 <span class="detail"></span>
    </div>
  • detail.js

    1
    2
    3
    4
    5
    (function () {
    var num = single.getParams();
    console.log(num);
    document.getElementsByClassName('detail')[0].innerText = num.id;
    })();

然后我们看看实现脚本(loadjs会在页面添加重复的脚本,还没想好怎么解决)

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
91
92
93
94
var single = (function () {
var singlePageZIndex = 1;

var singlePage = {
//页面初始化
init: function () {
var self = this;
var link = window.location.href;
var routerName = link.split('#')[1] || '';
window.onload = function () {
if (routerName != '' && routerName != routerHome.home) {
singlePage.replace(routerName, history.state);
} else {
self.renderPage(routerHome);
singlePage.loadJs(routerHome);
}
}
},
//根据url传入router的值渲染页面
renderPage: function (singleData) {
var html = '<div class="singleContentBox" style="z-index: ' + singlePageZIndex + '">';
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", singleData.template, true);
xmlhttp.send();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var div = document.createElement('div');
div.innerHTML = html + xmlhttp.responseText + '</div>';
document.getElementsByTagName("body")[0].appendChild(div);
singlePageZIndex++;
}
}
},
//动态加载脚本
loadJs: function (singleData) {
var oHead = document.getElementsByTagName('head').item(0);
var oScript= document.createElement("script");
oScript.type = "text/javascript";
oScript.src=singleData.controller;
oHead.appendChild(oScript);
},
//返回后去掉加载进来的页面模块
removePage: function () {
var pages = document.getElementsByClassName('singleContentBox');
if (pages.length > 1) {
pages[pages.length - 1].remove()
}
singlePageZIndex--;
},
//页面跳转
go: function (key, params) {
singlePage.loadJs(router[key]);
singlePage.renderPage(router[key]);
if (params != undefined && typeof params === "object") {
history.pushState(params, key, '#' + key);
} else {
history.pushState({}, key, '#' + key);
}
},
//页面返回
back: function () {
this.removePage();
history.back();
},

replace: function (key, params) {
singlePage.loadJs(router[key]);
singlePage.renderPage(router[key]);
if (params != undefined && typeof params === "object") {
history.replaceState(params, key, '#' + key);
} else {
history.replaceState({}, key, '#' + key);
}
},
//获取传值
getParams: function () {
return history.state;
}
};

singlePage.init();

window.addEventListener('popstate', function(e){
//返回触发后调用移除页面模块
singlePage.removePage();
},false);

return {
go: singlePage.go,
back: singlePage.back,
replace: singlePage.replace,
getParams: singlePage.getParams
}
})();