pushstate能否触发onhashchange事件?

点击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>
阅读 3.7k
1 个回答

pushState是不触发任何事件的,像popstate也不会触发。你需要调用完pushState后再调用一次你的refresh方法就好

换一个角度看,我们可以通过pushState、前进、后退改变url,而只有pushState是不会触发popstate事件的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题