Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
314 views
in Technique[技术] by (71.8m points)

javascript - 如何为SPA创建普通的JS路由?(How to create a vanilla JS routing for SPA?)

I'm creating a web app with NO frameworks/tools/libraries.

(我正在创建一个没有框架/工具/库的Web应用程序。)

Why?

(为什么?)

It doesn't matter.

(没关系)

All Vanilla JS.

(所有Vanilla JS。)

I'm doing it more of 'React' style.

(我正在做更多的“反应”风格。)

I'm wondering, how can I call the view that are in my views/pages/dashboard.js and display that when the user click the dashboard nav link?

(我想知道,当用户单击仪表板导航链接时,如何调用我的views / pages / dashboard.js中的视图并显示该视图?)

Perhaps the sub-nav items.

(也许是子导航项。)

What if the user is in the github folder on profile, how would I display that in the url as well?

(如果用户位于个人资料上的github文件夹中,该如何在网址中显示呢?)

How can I create a routing for this?

(如何为此创建路由?)

I've read articles an watched YT videos but can't seem to implement it here.

(我已阅读了观看过的YouTube视频的文章,但似乎无法在此处实现。)

Here's the GitHUb repo: https://github.com/AurelianSpodarec/JS_GitHub_Replica/tree/master/src/js

(这是GitHUb仓库: https : //github.com/AurelianSpodarec/JS_GitHub_Replica/tree/master/src/js)

All the articles out there.

(所有的文章在那里。)

I'm pretty new so trying to figure this out.

(我很新,所以想弄清楚。)

This is what I've tried

(这就是我尝试过的)

document.addEventListener("DOMContentLoaded", function() {
    var Router = function (name, routes) {
        return {
            name: name,
            routes: routes
        }
    };
    var view = document.getElementsByClassName('main-container');
    var myRouter = new Router('myRouter', [
        {
            path: '/',
            name: "Dahsboard"
        },
        {
            path: '/todo',
            name: "To-Do"
        },
        {
            path: '/calendar',
            name: "Calendar"
        }
    ]);
    var currentPath = window.location.pathname;
    if (currentPath === '/') {
        view.innerHTML = "You are on the Dashboard";
        console.log(view);
    } else {
        view.innerHTML = "you are not";
    }
});

When the user clicks an item on the nav, show load the view.

(当用户单击导航上的项目时,显示将加载视图。)

So this is the navbar: https://codepen.io/Aurelian/pen/EGJvZW and I want to load the right view and change the url.

(所以这是导航栏: https : //codepen.io/Aurelian/pen/EGJvZW ,我想加载正确的视图并更改URL。)

  ask by Luigi translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As i said in the comments, listening for popstate and using the hashtag ( # ) method is the easiest way to do routing in JS.

(就像我在评论中说的那样,侦听popstate并使用popstate# )方法是在JS中进行路由的最简单方法。)

This is the most bare bones for a router:

(这是路由器最裸露的骨头:)

 //App area var appArea = document.body.appendChild(document.createElement("div")); //Registered routes var routes = [ { url: '', callback: function () { appArea.innerHTML = "<h1>Home</h1><a href=\"#todo\">To-Do</a><br/><a href=\"#calendar\">Calendar</a>"; } } ]; //Routing function function Routing() { var hash = window.location.hash.substr(1).replace(/\//ig, '/'); //Default route is first registered route var route = routes[0]; //Find matching route for (var index = 0; index < routes.length; index++) { var testRoute = routes[index]; if (hash == testRoute.url) { route = testRoute; } } //Fire route route.callback(); } //Listener window.addEventListener('popstate', Routing); //Initial call setTimeout(Routing, 0); //Add other routes routes.push({ url: "todo", callback: function () { appArea.innerHTML = "<h1>To-Do</h1><a href=\"#\">Home</a><br/><a href=\"#calendar\">Calendar</a>"; } }); routes.push({ url: "calendar", callback: function () { appArea.innerHTML = "<h1>Calendar</h1><a href=\"#\">Home</a></br><a href=\"#todo\">To-Do</a>"; } }); 

Now in any real context you would want reusable DOM elements and scope-unload functions so here is how the above should probably look:

(现在,在任何实际环境中,您都需要可重用的DOM元素和作用域卸载功能,因此,上面的内容应如下所示:)

 // ## Class ## // var Router = /** @class */ (function () { function Router() { } //Initializer function. Call this to change listening for window changes. Router.init = function () { //Remove previous event listener if set if (this.listener !== null) { window.removeEventListener('popstate', this.listener); this.listener = null; } //Set new listener for "popstate" this.listener = window.addEventListener('popstate', function () { //Callback to Route checker on window state change this.checkRoute.call(this); }.bind(this)); //Call initial routing as soon as thread is available setTimeout(function () { this.checkRoute.call(this); }.bind(this), 0); return this; }; //Adding a route to the list Router.addRoute = function (name, url, cb) { var route = this.routes.find(function (r) { return r.name === name; }); url = url.replace(/\//ig, '/'); if (route === void 0) { this.routes.push({ callback: cb, name: name.toString().toLowerCase(), url: url }); } else { route.callback = cb; route.url = url; } return this; }; //Adding multiple routes to list Router.addRoutes = function (routes) { var _this = this; if (routes === void 0) { routes = []; } routes .forEach(function (route) { _this.addRoute(route.name, route.url, route.callback); }); return this; }; //Removing a route from the list by route name Router.removeRoute = function (name) { name = name.toString().toLowerCase(); this.routes = this.routes .filter(function (route) { return route.name != name; }); return this; }; //Check which route to activate Router.checkRoute = function () { //Get hash var hash = window.location.hash.substr(1).replace(/\//ig, '/'); //Default to first registered route. This should probably be your 404 page. var route = this.routes[0]; //Check each route for (var routeIndex = 0; routeIndex < this.routes.length; routeIndex++) { var routeToTest = this.routes[routeIndex]; if (routeToTest.url == hash) { route = routeToTest; break; } } //Run all destroy tasks this.scopeDestroyTasks .forEach(function (task) { task(); }); //Reset destroy task list this.scopeDestroyTasks = []; //Fire route callback route.callback.call(window); }; //Register scope destroy tasks Router.onScopeDestroy = function (cb) { this.scopeDestroyTasks.push(cb); return this; }; //Tasks to perform when view changes Router.scopeDestroyTasks = []; //Registered Routes Router.routes = []; //Listener handle for window events Router.listener = null; Router.scopeDestroyTaskID = 0; return Router; }()); // ## Implementation ## // //Router area var appArea = document.body.appendChild(document.createElement("div")); //Start router when content is loaded document.addEventListener("DOMContentLoaded", function () { Router.init(); }); //Add dashboard route Router.addRoute("dashboard", "", (function dashboardController() { //Scope specific elements var header = document.createElement("h1"); header.textContent = "Dashboard"; //Return initializer function return function initialize() { //Apply route appArea.appendChild(header); //Destroy elements on exit Router.onScopeDestroy(dashboardExitController); }; //Unloading function function dashboardExitController() { appArea.removeChild(header); } })()); //Add dashboard route Router.addRoute("dashboard", "", (function dashboardController() { //Scope specific elements var header = document.createElement("h1"); header.textContent = "Dashboard"; var links = document.createElement("ol"); links.innerHTML = "<li><a href=\"#todo\">To-Do</a></li><li><a href=\"#calendar\">Calendar</a></li>"; //Return initializer function return function initialize() { //Apply route appArea.appendChild(header); appArea.appendChild(links); //Destroy elements on exit Router.onScopeDestroy(dashboardExitController); }; //Unloading function function dashboardExitController() { appArea.removeChild(header); appArea.removeChild(links); } })()); //Add other routes Router.addRoutes([ { name: "todo", url: "todo", callback: (function todoController() { //Scope specific elements var header = document.createElement("h1"); header.textContent = "To-do"; var links = document.createElement("ol"); links.innerHTML = "<li><a href=\"#\">Dashboard</a></li><li><a href=\"#calendar\">Calendar</a></li>"; //Return initializer function return function initialize() { //Apply route appArea.appendChild(header); appArea.appendChild(links); //Destroy elements on exit Router.onScopeDestroy(todoExitController); }; //Unloading function function todoExitController() { appArea.removeChild(header); appArea.removeChild(links); } })() }, { name: "calendar", url: "calendar", callback: (function calendarController() { //Scope specific elements var header = document.createElement("h1"); header.textContent = "Calendar"; var links = document.createElement("ol"); links.innerHTML = "<li><a href=\"#\">Dashboard</a></li><li><a href=\"#todo\">To-Do</a></li>"; //Return initializer function return function initialize() { //Apply route appArea.appendChild(header); appArea.appendChild(links); //Destroy elements on exit Router.onScopeDestroy(calendarExitController); }; //Unloading function function calendarExitController() { appArea.removeChild(header); appArea.removeChild(links); } })() } ]); 


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.8k users

...