
class EventBus{ events = {} on(event, cb){ let cbs = this.events[event] || []; this.events[event] = [...cbs, cb] } off(event, cb){ let cbs = this.events[event] || []; let index = cbs.indexOf(cb); if (index !== -1){ this.events[event].splice(index, 1); } } emit(event){ let cbs = this.events[event] || []; cbs.forEach(cb=>cb()) }}--------------------------------------------------------------------------<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>SPA的原生实现</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 src='./EventBus.js'></script> <script> let event = new EventBus(); function Router(options){ this.mode = options.mode || 'hash'; this.routes = options.routes || []; this.init = function(){ var eles = document.querySelectorAll('.router'); var that = this; [...eles].forEach(item=>{ item.addEventListener('click', function(e){ e.stopPropagation(); e.preventDefault(); var path = e.target.getAttribute('href'); var isReplace = e.target.getAttribute('replace'); console.log('path...', path, isReplace); if (that.mode == 'hash'){ if (isReplace){ let index = window.location.href.indexOf('#'); window.location.replace(`${window.location.href.slice(0, index)}#${path}`); }else{ window.location.hash = `#${path}`; } }else{ if (isReplace){ window.history.replaceState('', '', path); }else{ window.history.pushState('', '', path); } event.emit('popstate'); } }) }) // 监听相关事件 if (this.mode === 'hash'){ window.addEventListener('hashchange', this.routeChange.bind(this)) }else{ window.addEventListener('popstate', this.routeChange.bind(this)) event.on('popstate', this.routeChange.bind(this)); } // 初始化routeChange this.routeChange(); } // 响应路由变化 this.routeChange = function(){ let routerView = document.querySelector('#router-view'); console.log('routeChange...'); if (this.mode === 'hash'){ let path = window.location.hash.slice(1); let index = this.routes.findIndex(item=>item.path === path); if (index !== -1){ routerView.innerHTML = this.routes[index].component; }else{ let matchAllIndex = this.routes.findIndex(item=>item.path === '*') if (matchAllIndex !== -1){ let index = window.location.href.indexOf('#'); window.location.replace(`${window.location.href.slice(0, index)}#${this.routes[matchAllIndex].redirect}`); } } }else{ let path = window.location.pathname; let index = this.routes.findIndex(item=>item.path === path); if (index !== -1){ routerView.innerHTML = this.routes[index].component; }else{ let matchAllIndex = this.routes.findIndex(item=>item.path === '*') if (matchAllIndex !== -1){ let index = window.location.href.indexOf('#'); window.history.replaceState('', '', this.routes[matchAllIndex].redirect); } } } } 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>