ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

前端 JS 原生 javascript 和 location.hash 实现一个单页应用的路由 router

2021-04-17 23:01:48  阅读:182  来源: 互联网

标签:hash route javascript JS routes Router id 路由


 开篇日常立个flag……

 

前言

最近在做一些应用,类似于单页应用,想实现类似于 Vue 路由的效果。

但是个人 Vue 基础四舍五入约等于无,而且看着 Vue-router 吃力+用不起来(因为我的项目前后端不分离,而且使用的 js 语法基本上停留在远古时代:ES5甚至更久远以前……)

之前尝试过模拟,但是模拟太痛苦了,而且一堆问题,还不好维护。

于是想着自己用原生 js 写一个简单的单页应用路由吧。

 

效果

话不多说,先上效果图

 

源码

gitee:https://gitee.com/chen3322275/singlepagerouter/

 

思路与设定

-思路

1、location.hash 可以修改页面的锚点

2、当前页面锚点的改变,会触发 hashchange 事件

这样,注册一个 hashchange 事件,监听 hash 的变化,切换页面指定元素的显示与隐藏,可以达到单页应用的效果。

-一些设定

首先我们约定一个路由对象 route,route 包含两个属性,即 id 和 handle。

接着,我们将会设定一个路由表,记录为 routes,为一个 route 对象的数组。

最后,实现一个路由器 Router 对象,还监听以及操作路由跳转。

三者的定义如下:

//route 单个路由对象
var route = { id: 'next', handle: function () { console.log("切换到next");}

//routes 路由表
var routes = [{ id: 'index' }, { id: 'next', handle: function () { console.log("切换到next");} }]

//router 路由器
var router = new Router(routes);

注释:

route 对象的 id,除了为操作元素(一般为 div)的 id 外,还将会是 hash 的值。

handle 为一个函数,类似于回调函数,在切换该路由时执行。

若 id 为空,则隐藏路由表所有路由。

 

Router 模块 js代码

直接上代码

/*
 * 模块:单页应用路由
 * 作者:cls
 * 日期:2021.04.17
 * 使用:var routes = [{ id: 'index' }, { id: 'next', handle: function () { console.log("切换到next");} }]
 *       var router = new Router(routes);
 */
function Router(routes, defaultRoute) {
    var othis = this;

    //路由初始化
    routes && othis.init(routes, defaultRoute);

    //绑定 hashchange 事件
    window.addEventListener("hashchange", function() {
        let route = location.hash.slice(1) || "";
        othis.oldRoute = othis.currentRoute;
        othis.currentRoute = route;
        othis.changePage(route);
    });
}

//初始化,可多次初始化
Router.prototype.init = function(routes, defaultRoute) {
    if (routes == undefined || routes.length == undefined || routes.length == 0) {
        console.error("Router初始化失败:routes错误!");
        return;
    }
    this.routes = routes;
    this.currentRoute = location.hash.slice(1) || defaultRoute || routes[0].id; //当前路由获取顺序
    this.oldRoute = "";
    location.hash || history.replaceState(null, null, '#' + this.currentRoute); //hash为空,切换当前hash
    this.changePage(this.currentRoute);
    this.oldRoute = location.hash;
}

//切换路由
Router.prototype.push = function(route, callback) {
    //获取route
    switch (typeof(route)) {
        case "string":

            break;
        case "undefined":
            route = location.hash.slice(1) || "";
            break;
        case "number":
            route = this.routes[route] || "";
            break;
        case "object":
            route = route.id || "";
            break;
    }
    location.hash = route; //切换hash,接下来的事情交给hashchange去做。如果与上一次的route一致,不会触发hashchange事件
}

//切换页面:route为字符串,为空则隐藏所有路由
Router.prototype.changePage = function(route) {
    for (let i = 0; i < this.routes.length; i++) {
        let e = document.getElementById(routes[i].id);
        if (routes[i].id == route) {
            e && (e.style.display = "block");
            (typeof(routes[i].handle) === "function") && routes[i].handle(); //handle 存在,执行函数
        } else {
            e && (e.style.display = "none");
        }
    }
}

  

测试页面的 Html 代码

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>单页路由测试</title>
</head>
<body>
    <div>
        <h1>Welcome</h1>

        <a href="#">空的</a>
        <a href="#index">index啊啊啊</a>
        <button onclick="router.push('next')">next测试</button>

        <div id="index">
            index啊啊啊
        </div>
        <div id="next">
            next啊啊啊 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
        </div>
    </div>

    <script src="~/js/site.js"></script>
    <script>
        //路由表
        var routes = [
            { id: '' },
            { id: 'index' },
            { id: 'next', handle: function () { console.log("切换到next"); console.log(this); } }
        ]

        //路由器
        var router = new Router(routes, 'index');
    </script>
</body>
</html>

  

使用说明

1、整个应用生命周期,只创建一次路由器,即 var router = new Router() 时,只 new 一次。(否则会注册多次 hashchange 事件)

2、路由器创建以后,可以使用 router.init() 切换路由表

3、控制 router 跳转路由使用 router.push(route) 方法,输入的 route 可以是路由表的下标,也可以是路由表 id 的字符串,也可以是 route 对象,若没有输入,则默认不会跳转。

 

 参考来源

鱼丸粗面不要香菜 的 使用js实现单页应用路由转跳功能

小蚊 的 用原生js做单页应用(博文挂掉了,链接复制不到)

标签:hash,route,javascript,JS,routes,Router,id,路由
来源: https://www.cnblogs.com/clis/p/14672179.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有