单页面应用SPA路由实现

实现流程

流程

代码实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>原生实现hash和browser两种路由模式</title>
</head>
<body>
    <div class="router_box">
        <a href="/home" class="router" replace="true">主页</a>
        <a href="/news" class="router">新闻</a>
        <a href="/team" class="router">团队</a>
        <a href="/about100" class="router">关于</a>
    </div>
    <div id="router-view"></div>

    <script>
         function Router(params){
            // 记录routes配置
            this.routes  = params.routes||[];
            // 记录路由模式
            this.mode = params.mode||'hash';
            //初始化
            this.init = function(){
                var that = this;
                //绑定路由响应事件
                document.querySelectorAll('.router').forEach((item,index)=>{
                  //a标签的点击事件
                  item.addEventListener('click',function(e){
                       //阻止a标签的默认行为
                   if(e&&e.preventDefault){
                        e.preventDefault()
                   }else{
                       window.e.returnValue = false
                   }
                //    判断是hash路由还是history路由
                   if(that.mode=='hash'){
                       if(this.getAttribute('replace')){
                            var i = window.location.href.indexOf('#');
                            // 通过replace方法直接替换url
                            window.location.replace(window.location.href.slice(0,i>0?i:0+'#'+this.getAttribute(href)))
                       }else{
                           window.location.hash= this.getAttribute('href')
                       }
                   }else{
                       //判断是push方法,还是replace方法
                       if(this.getAttribute('replace')){
                            window.history.replaceState({},'',window.location.origin+this.getAttribute('href'))
                       }else{
                        window.history.pushState({},'',window.location.origin+this.getAttribute('href'))
                       }
                   }
                   that.routerChange()
                  },false)

                //   路由变化后,更新内容
                if(this.mode=='hash'){
                    window.addEventListener('hashchange',()=>{
                        this.routerChange()
                    })
                }else{
                    window.addEventListener('propstate',()=>{
                        this.routerChange()
                    })
                }
                this.routerChange()
                })
            },
            this.routerChange=function(){
                if(this.mode=='hash'){
                    let nowHash = window.location.hash;
                    let index = this.routes.findIndex((item,index)=>{
                        return nowHash==('#'+item.path)
                    })
                   if(index>=0){
                       document.getElementById('router-view').innerHTML=this.routes[index].component
                   }else{
                    //    如果没有找到相应的路由,则去找有没有*
                    let defaultRoute = this.routes.findIndex(item=>{
                        return item.path == '*'
                    })
                    // 找到*执行重定向
                    if(defaultRoute>=0){
                        var i = window.location.href.indexOf('#');
                        // 用replace直接替换路由
                        // window.location.replace(
                        //         window.location.href.slice(0, i >= 0 ? i : 0) + '#' + this.routes[defaultIndex].redirect
                        //     )
                        window.location.hash= this.routes[defaultRoute].redirect
                            
                    }
                   }
                   
                }else{
                   let path = window.location.href.replace(window.location.origin,'')
                  
                   let index = this.routes.findIndex(item=>{
                       return path==item.path
                   })
                   if(index>=0){
                    document.getElementById('router-view').innerHTML=this.routes[index].component
                   }else{
                    let defaultRoute = this.routes.findIndex(item=>{
                        return item.path == '*'
                    })
                  
                    // 找到*执行重定向
                    if(defaultRoute>=0){
                        
                        // 用replaceState直接替换路由
                        // window.history.replaceState({},'',window.location.origin + this.routes[defaultRoute].redirect)                    
                        window.history.pushState({},'',window.location.origin+this.routes[defaultRoute].redirect)
                            this.routerChange()
                    }
                   }
                }
            }
            this.init()
        }
         new Router({
            mode: 'hash',
            routes:[
                { path: '/home', component: '<h1>主页</h1><h4>新一代前端工程师:我们啥都会</h4>' },
                { path: '/news', component: '<h1>新闻</h1><h4>今天2018-11-5,上课还得穿工装</h4>' },
                { path: '/team', component: '<h1>团队</h1><h4>WEB前端工程师</h4>' },
                { path: '/about', component: '<h1>关于</h1><h4>一面而高薪就业</h4>' },
                { path:'*', redirect:'/home'}
            ]
        });

    </script>
</body>
</html>

兼容问题

ie9及以下不支持html5 history新特性,可引入history库

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值