原生js实现一个hash路由
仓库地址:https://gitee.com/littleboyck/front.git
目录所在位置:router文件夹
index.html的<body>中 <div id="app"></div>
<script src="./lib/Router.js"></script>
view文件夹中新建layout.html <div class="layout-fluid"> <div><a r-link="#/home">首页</a></div> <div><a r-link="#/button">按钮组件</a></div> <div><a r-link="#/form">表单组件</a></div> <div><a r-link="#/bdage">徽章组件</a></div> <div id="app-body" class="layadmin-tabspage-none"></div> </div>
class Router{ constructor(options){ //缓存route数据信息 this.routes = {}; this.options = options; this.ready(); } //伪数组转为真数值 static arrayLike(arrLike){ return Array.from ? Array.from(arrLike) : Array.prototype.slice.call(arrLike); } static isLikeArr(el){ return typeof el == 'object' && !(el instanceof Array) && el.length>0 ? true : false; } static isDOM(el){ return el.nodeType == (Node.ELEMENT_NODE||Node.DOCUMENT_NODE) || Router.isLikeArr(el); } static getEl(selector){ if(selector.nodeType != (Node.ELEMENT_NODE||Node.DOCUMENT_NODE)){ if(/^#[^#\s\b]+$/.test(selector)){ selector = document.querySelector(selector) }else{ selector = document.querySelectorAll(selector) } } return selector; } static animationEnd(ele,sucHandle){ //1、获取动画名 let animateName = function(){ const animation = { 'animation': 'animationend', 'OAnimation': 'oAnimationEnd', 'MozAnimation': 'mozAnimationEnd', 'WebkitAnimation': 'webkitAnimationEnd' } const animateName = (function(el) { for (let t in animation) { if (el.style[t] !== undefined) { return animation[t]; } } })(document.createElement('div')); return animateName; }(); //2、给ele绑定动画结束的回调 const animateEndEventListener = function(sucHandle){ //在每次transitionEnd的事件后执行该函数 const handleAniEnd = function(e){ ele.removeEventListener(animateName,handleAniEnd); sucHandle.call(this,e,ele); }; ele.addEventListener(animateName,handleAniEnd,false); } animateName && animateEndEventListener(sucHandle) } static evtListener(el,event,handle){ el = Router.isDOM(el) ? [...el] : [el]; el.forEach(el=>el.addEventListener(event,handle)); } static removeListener(el,event,handle){ el = Router.isDOM(el) ? [...el] : [el]; el.forEach(el=>el.removeEventListener(event,handle)); } static isHash(val){ return /#[^#.]+/.test(val) } static evalScripts(text){ let script ,scripts = [] , regexp = /<script[^>]*>\s*([\s\S]*?)\s*<\/script>/gi; while(script = regexp.exec(text)){ scripts.push(script[1]) } scripts = scripts.join('\n'); //window.execScript只有ie有 scripts && (!window.execScript ? eval(scripts) : execScript(scripts)) } static setTitle(htmlString){ let result = /<title>([\s\S]*?)<\/title>/.exec(htmlString) ,title = result ? result[1] : htmlString; document.querySelectorAll('title')[0].textContent = title } parse(text){ Router.setTitle(text) document.querySelector(this.options.routerView).innerHTML = text; Router.evalScripts(text) } //收集routes route(path,callback){ this.routes[path] = callback ? callback : function(){}; } //重定向会改变hash redirect(path){ location.hash != path && (location.hash = path) } //跳转是内部行为,不改变hash forward(path){ this.routes[path] && this.routes[path].call(this) } init(firstPath){ let curHash = location.hash; curHash && (firstPath = curHash) Router.isHash(firstPath) && (location.hash = firstPath) && curHash && this.forward(firstPath) } //监听hashchange listenerHashchange(){ Router.evtListener(window,'hashchange',()=>{ this.forward(location.hash) }); } //初始化 ready(){ this.listenerHashchange(); } }
//使用方式:
let router = new Router({
routerView:'#app-body'
})
//1、注册routes依赖
router.route("#/home",function(){
router.parse("hello home page !!")
})
router.route("#/button",function(){
$.ajax({url:'./component/button.html'}).then(function(html){
router.parse(html);
})
})
router.route("#/bdage",function(){
$.ajax({url:'./component/bdage.html'}).then(function(html){
router.parse(html);
})
})
router.route("#/form",function(){
$.ajax({url:'./component/element.html'}).then(function(html){
router.parse(html);
})
})
$.ajax({url:'./view/layout.html'}).then(function(html){
document.querySelector("#app").innerHTML = html;
//2、初始化默认页
router.init('#/home')
Router.evtListener(document.querySelectorAll('[r-link]'),'click',function (e) {
router.redirect(this.getAttribute('r-link'))
})
})