点击a标签改变hash后能触发onhashstate事件,我想用H5的pushstate测试下,将a标签换成span,监听span的click事件用pushstate,hash是变化了,可是并没有触发onhashchange事件,但是浏览器的回退按钮可以触发popstate可以正常触发,为什么?
代码如下:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style type="text/css">
* {
margin: 0;
padding: 0;
font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;
}
a{
text-decoration: none;
}
html {
font-size: 62.5%;
}
ul {
list-style: none;
}
header .head {
width: 100%;
height: 4rem;
background-color: #985f0d;
list-style: none;
display: flex;
}
header .head .head-list {
flex: 1;
height: 100%;
color: #FFF;
line-height: 4rem;
font-size: 2rem;
text-align: center;
box-sizing: border-box;
}
header .head .head-list + .head-list {
border-left: 1px solid #FFF;
}
header .head .head-list .head-list-go {
display: block;
height: 100%;
color: #FFF;
}
.content{
position: absolute;
top:4rem;
left:0;
right:0;
bottom:0;
/* height:100%;*/
background-color: #d98713;
}
.recommend, .bookcity{
display: none;
}
.bookshelves .book-preview{
padding: 1.5rem;
}
.bookshelves .book-preview .book-title{
display: flex;
width:100%;
}
.bookshelves .book-preview .book-title .title-list{
flex:1;
box-sizing: border-box;
margin:1rem 0.7rem;
padding: 0.8rem;
width:25%;
height:14rem;
background-color: rgb(0,164,255);
}
</style>
<title>H5</title>
</head>
<body>
<header>
<ul class="head">
<li class="head-list"><span id="list-recommend" class="head-list-go" href="#/recommend">推荐</span></li>
<li class="head-list"><span id="list-bookcity" class="head-list-go " href="#/bookcity">书城</span></li>
<li class="head-list"><span id="list-bookshelves" class="head-list-go " href="#/bookshelves">书架</span></li>
</ul>
</header>
<div class="content">
<div class="recommend">推荐</div>
<div class="bookcity">书城</div>
<div class="bookshelves">
<div class="book-preview">
<ul class="book-title">
<li class="title-list"><a href="">麻雀麻雀麻雀麻雀麻雀麻雀麻雀</a></li>
<li class="title-list"><a href="">黄金黄金黄金黄金黄金黄金</a></li>
<li class="title-list"><a href="">时代时代时代时代时代时代时代</a></li>
</ul>
</div>
</div>
</div>
<script type="text/javascript">
/**
* Created by 张洋 on 17-7-15.
*/
function H5router() {
this.routers = {};
this.init();
}
H5router.prototype = {
route: function (url, cb) {
let newurl = url ||'';
this.routers[newurl] = cb || function () {};
},
init:function () {
let head = document.getElementsByClassName('head')[0];
Array.from(head.children).forEach(function (ele) {
ele.addEventListener('click',function (e) {
console.log('click')
let target = e.target || e.srcElement;
let className = target.id.substr(5);
window.history.pushState(null,className,'http://localhost:63342/after20170606/nodeBook/html/indexH5.html#/'+className);
});
});
window.addEventListener('hashchange', this.refresh.bind(this));
window.addEventListener('popstate', this.refresh.bind(this));
},
refresh:function () {
let hash = location.hash.substr(1) || '/';
hash = '#'+hash;
console.log('changing*******',hash);
console.log(this.routers[hash])
this.routers[hash]();
},
hideOther: function () {
let head = document.getElementsByClassName('head')[0];
let content = document.getElementsByClassName('content')[0];
let className = location.hash.substr(2) || '/';
console.log('cnh5',className);
Array.from(content.children).forEach(function (ele) {
if (ele.className.indexOf(className) === -1) {
ele.style.display = 'none';
} else {
ele.style.display = 'block';
}
});
}
};
let h5route = new H5router();
h5route.route('#/recommend', () => {
h5route.hideOther();
});
h5route.route('#/bookcity', () => {
h5route.hideOther();
});
h5route.route('#/bookshelves', () => {
h5route.hideOther();
});
</script>
</body>
</html>
pushState是不触发任何事件的,像popstate也不会触发。你需要调用完pushState后再调用一次你的refresh方法就好
换一个角度看,我们可以通过pushState、前进、后退改变url,而只有pushState是不会触发popstate事件的。