美文网首页H5开发Vue.js专区
H5 路由的两种实现

H5 路由的两种实现

作者: 风之化身呀 | 来源:发表于2017-07-09 15:14 被阅读716次

    1、原理浅析

    • hash模式
      如果a标签的href属性以"#"开头,那么当点击这个a标签时就会触发hashchange事件,在该事件处理函数中可以做很多事,比如发ajax请求,进行DOM操作替换页面等。
    • history模式
      hisroty模式相比hash模式,是一种比较新的路由模式,其浏览器兼容性如下:
    pushState浏览器兼容性

    原理就是利用history.pushState(state,null,url)更新浏览器url地址

    2、具体实现

    Talk is easy,show you the Code!

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hash Test</title>
    </head>
    <body>
        <a href="#1">#1</a>
        <a href="#2">#2</a>
        <div id="content"></div>
        <script type='text/js-template' class="test" id="1">第一页</script>
        <script type='text/js-template' class="test" id="2">第二页</script>
        <script type="text/javascript">
            //1、选取元素
            var aElm=document.getElementsByTagName('a');
            var array=[].slice.call(aElm)
            var content=document.getElementById('content')
            //2、特性检测,如果支持history模式就用history,否则用hash模式
            if (history&&history.pushState) {
                window.addEventListener('popstate',handlePage);
                //劫持a元素的click事件,主要是为了更新history.state的状态以及替换url,当点击url跳转时先执行onclick再触发popstate
                array.forEach(function(v){
                    v.onclick=function(event){
                        var path=event.target.hash.split("#")[1];
                        var newUrl=location.href.split('#')[0]+'\/'+path;
                        history.pushState({current:path},null,newUrl)
                    }
                })
            } else {
                window.addEventListener('hashchange',handlePage);
            }
                 //3、统一使用handlePage作为两种模式的事件处理器
            function handlePage(){
                if (history&&history.pushState) {
                    var current=history.state&&history.state.current||'1';
                    render(current)
                } else {
                    var hash=location.hash||'#1';
                    render(hash,true)
                }
                function render(selector,isHashMode){
                    var hashMode=isHashMode&&true;
                    var select='';
                    if (hashMode) {
                        select=selector.split('#')[1];
                    } else {
                        select=selector||history.state.current
                    }
                    var toPage=document.getElementById(select);
                    content.innerHTML=toPage.innerHTML;
                }
            }
            handlePage();
        </script>
    </body>
    </html>
    

    3、需要注意的地方

    • pushState的第三个参数url是不能跨域的
    • pushState并不能触发popstate事件,只有浏览器的前进返回才能触发popstate

    参考:单页面应用路由实现原理:以 React-Router 为例

    相关文章

      网友评论

      本文标题:H5 路由的两种实现

      本文链接:https://www.haomeiwen.com/subject/eigshxtx.html