前言
先来介绍一下history.pushState()和window.onpopstate
history.pushState(),改变当前地址栏的路径,并不会更新页面内容
用法:history.pushState(Object, title, url);
- 第一个参数:是一个对象,通过pushState方法可以将该对象内容传递到新页面中。
- 第二个参数,指标题,几乎没有浏览器支持该参数,传一个空字符串比较安全。
- 第三个参数,是新的路径地址,不指定的话则为当前的路径。
window.onpopstate,该事件可以监听,点击浏览器的前进按钮/后退按钮
调用history.pushState()或history.replaceState()不会触发popstate事件。该popstate事件仅通过执行浏览器操作触发,如单击“后退”按钮(或JavaScript中调用history.back()),在同一文档的两个历史记录项之间进行导航。
window.addEventListener('popstate', function (e) {
});
history.pushState()案例:
来看一下我们要实现的tab切换的最终效果:
当点击水果、蔬菜、零食、饮料菜单时,下方会出现对应的内容
布局代码:
<ul id="menu">
<li>水果</li>
<li>蔬菜</li>
<li>零食</li>
<li>饮料</li>
</ul>
<ul id="list1">
<li>猕猴桃</li>
<li>苹果</li>
<li>梨</li>
</ul>
<ul id="list2">
<li>白菜</li>
<li>土豆</li>
<li>地瓜</li>
</ul>
<ul id="list3">
<li>辣条</li>
<li>牛肉干</li>
<li>薯片</li>
</ul>
<ul id="list4">
<li>可乐</li>
<li>雪碧</li>
<li>果汁</li>
</ul>
样式代码:
#menu {
list-style: none;
margin: 0;
padding: 0;
position: relative;
height: 200px;
}
#menu>li {
float: left;
margin-left: 20px;
padding: 10px 30px;
border: 1px solid #000000;
}
ul:not(#menu) {
position: absolute;
display: none;
}
js代码:
var menu = document.getElementById("menu");
//将获取到的htmlCollection列表转成数组
var lis = Array.from(menu.getElementsByTagName("li"));
var uls = Array.from(document.getElementsByTagName("ul")).slice(1);
//监听浏览器的前进、回退按钮
window.onpopstate = function () {
changeList();
}
//给上面每个li添加点击事件
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = clickHandler
}
function clickHandler() {
var index = lis.indexOf(this);
//将id数据传到新的页面,同时给当前的链接添加锚点标记
history.pushState({ id: "list" + (index + 1) }, "", "#list" + (index + 1));
changeList();
}
function changeList() {
for (var i = 0; i < uls.length; i++) {
//如果ul列表的id等于history中传过来的数据,则让对应的ul显示,否则让它隐藏
if (uls[i].id === history.state.id) {
uls[i].style.display = "block";
} else {
uls[i].style.display = "none";
}
}
}
这个案例中,给当前浏览器的路径添加锚点,只是为了更清楚地看到页面路径的改变,如果不修改当前的页面路径,也不会影响tab功能的实现。