用户的每次操作不一定会打开一个全新的页面,因此“后退”和“前进”按钮也就失去了作用,导致用户很难在不同状态间切换。下面给出两种解决方式:
- hashchange事件
- history.pushState()方法
一、hashchange事件
在window
对象上添加hashchange事件,当页面URL的hash(#后面)部分发生变化,就会调用该事件处理程序。hashchange事件的event对象包含oldURL和newURL两个属性,分别保存着参数列表前后的完整url。当url参数列表发生变化,我们可以在事件处理程序中做一些事情
<!doctype html><!--声明当前文档为html文档-->
<html lang="en"><!--语言为英语-->
<head><!--头部-->
<meta charset="UTF-8"><!--字符编码:utf-8国际编码 gb2312中文编码-->
<meta name="Keywords" content="关键词">
<meta name="Description" content="描述">
<title>Document</title>
<style>/*css样式表的衣柜*/
*{margin:0px;padding:0px;}
#nav{
width:900px;height:50px;background:rgba(0,0,0,0.5);
margin:100px auto;
}
li{
list-style:none;
width:100px;height:100%;
color:#fff;line-height:50px;text-align:center;
float:left;
cursor:pointer;
}
.curr{
background:red;
}
</style>
</head>
<body><!--身体-->
<div id="nav">
<ul id="u">
<li data-sum="0">主页</li>
<li data-sum="1">日志</li>
<li data-sum="2">相册</li>
<li data-sum="3">留言板</li>
<li data-sum="4">说说</li>
<li data-sum="5">个人档</li>
<li data-sum="6">音乐</li>
<li data-sum="7">时光轴</li>
<li data-sum="8">更多</li>
</ul>
</div>
<button id="btn">按钮</button>
<script>
// 状态管理:1、通过hashchange事件。当url的hash改变时触发hashchange事件(点击后退前进按钮)2、通过history.pushState(),当点击后退按钮触发window的poststate事件,在poststate中处理
var ul = document.getElementById("u");
var child=ul.children
len=child.length
//方式1 hashchange
u.onclick=function(e){
for(let i=0;i<len;i++){
child[i].classList.remove('curr')
}
e.target.classList.add('curr')
location.hash=e.target.dataset.sum
// console.log(e.target.innerText)
}
//点击后退和前进按钮,可以返回到走过的路,在事件处理程序中添加样式
window.onhashchange=function(e){
var n=parseInt(location.hash.slice(1))
for(let i=0;i<len;i++){
child[i].classList.remove('curr')
}
child[n].classList.add('curr')
console.log(e.oldURL)
console.log(e.newURL)
}
</script>
</body>
</html>
二、history.pushState()方法
history.pushState(),接受三个参数:状态参数、新状态的标题和相对的url。
history.pushState({name:"Nicholas"}, "Nicholas' page", "nicholas.html");
执行pushState()后,新的状态信息会被推入历史状态栈,而浏览器状态栏也会变成"相对的url"(第三个参数)。但是浏览器并不会向服务器发送请求,即便是location.url也返回状态栏的地址。由于pushState()方法是新建状态并推入栈,所以当点击后退按钮后,就会返回上一个地址。按下后退按钮,就会触发poststate事件,该事件也是window对象的
<!doctype html><!--声明当前文档为html文档-->
<html lang="en"><!--语言为英语-->
<head><!--头部-->
<meta charset="UTF-8"><!--字符编码:utf-8国际编码 gb2312中文编码-->
<meta name="Keywords" content="关键词">
<meta name="Description" content="描述">
<title>Document</title>
<style>/*css样式表的衣柜*/
*{margin:0px;padding:0px;}
#nav{
width:900px;height:50px;background:rgba(0,0,0,0.5);
margin:100px auto;
}
li{
list-style:none;
width:100px;height:100%;
color:#fff;line-height:50px;text-align:center;
float:left;
cursor:pointer;
}
.curr{
background:red;
}
</style>
</head>
<body><!--身体-->
<div id="nav">
<ul id="u">
<li data-sum="0">主页</li>
<li data-sum="1">日志</li>
<li data-sum="2">相册</li>
<li data-sum="3">留言板</li>
<li data-sum="4">说说</li>
<li data-sum="5">个人档</li>
<li data-sum="6">音乐</li>
<li data-sum="7">时光轴</li>
<li data-sum="8">更多</li>
</ul>
</div>
<button id="btn">按钮</button>
<script>
// 状态管理:1、通过hashchange事件。当url的hash改变时触发hashchange事件(点击后退前进按钮)2、通过history.pushState(),当点击后退按钮触发window的poststate事件,在poststate中处理
var ul = document.getElementById("u");
var child=ul.children
len=child.length
//方式2,pushState()
u.onclick=function(e){
for(let i=0;i<len;i++){
child[i].classList.remove('curr')
}
e.target.classList.add('curr')
history.pushState({name:'a'},'d','3.html#'+e.target.dataset.sum)
}
window.addEventListener("popstate",function (e) {
var n=parseInt(location.hash.slice(1))
for(let i=0;i<len;i++){
child[i].classList.remove('curr')
}
child[n].classList.add('curr')
},false)
</script>
</body>
</html>
参考资料
JavaScript高级程序设计(第3版)