创建模板 url-路由脚本

create a template url-routing script

我想尽可能地使用javascript创建一个url-routing脚本,但也在代码中接受jQuery . js 文件必须更改 url 路径(尽管我使用 location.hash 而不是 location.pathname)和带有 view[= 的 div 的内容38=] id(来自外部文件)相应。

示例配置:

  • root/index.html
  • root/tpl/home.html
  • root/tpl/about.html

home.html内容:

<p>This is content of home page</p>

about.html内容:

<p>This is the content of the about page </p>

到目前为止我做了什么:

'use strict';
var Router = {
root: '/',
routes: [],
urls: [],
titles: [],
navigate: function() {
    location.hash = this.root;
    return this;
},
add: function(thePath, theUrl, theTitle) {
    this.routes.push(thePath);
    this.urls.push(theUrl);
    this.titles.push(theTitle);
},
loading: function() {
    this.navigate();
    var r = this.routes;
    var u = this.urls;
    window.onload = function() {
        $("#view").load("tpl/home.html");
    };
    window.onhashchange = function() {
        for (var i = 0; i < r.length; i++) {
            if (location.hash == r[i]) {
                $("#view").load(u[i]);
            }
        }
    };
}
};
Router.add("#/home", "tpl/home.html", "Home Page");
Router.add("#/about", "tpl/about.html", "About Page");
Router.loading();

所需类型 url:

http://mywebsite.com/
http://mywebsite.com/about

我知道有足够多的库可以制作路由,例如 AngularJS 和 Crossroad,我想知道如何做到这一点。

为了使这个 URL 工作 - http://mywebsite.com/about - 你需要一个知道如何路由这个请求的服务器。由于实际文件名是 about.html,您的服务器必须知道如何处理无扩展名 URL。

通常,服务器使用文件扩展名作为提供内容的线索。例如,如果它看到 file.php 它知道使用 PHP 组件,对于 .aspx 它知道使用 ASP.NET 组件,对于 .htm.html 它知道用普通的 HTML 响应(并且通常提供文件而不是处理它)。您的服务器必须有一些规则来处理任何请求,无论它是否有扩展名,但如果没有扩展名,您需要为该请求提供明确的路由规则..

JavaScript 进行路由的能力是有限的,因为它要求用户已经在您的网站上。如果您解析 URL 参数或使用散列并将它们用于路由,您 可以 做一些有趣的事情,但这仍然需要从您的站点请求页面作为第一步。

例如:当您向服务器发出以下请求时,服务器已经在执行某种程度的 "extensionless routing":

http://mywebsite.com/

URL的部分是:

  • http - 协议
  • (隐含端口 80,因为它是默认的 HTTP 端口)
  • mywebsite.com - 域名又名主机
  • /路径

服务器看到 / 并使用 IIS 调用的 "default document"(我认为 apache 调用它 "default index" 或 "default page")。在这种情况下,服务器已配置为 return 文件,例如 "index.html" 或 "default.htm"。因此,当您请求 http://mywebsite.com/ 时,您实际上可能会得到 http://mywebsite.com/index.html

的等价物

当服务器看到 http://mywebsite.com/about 时,它可能首先查找名为 about 的文件夹,然后查找名为 about 的文件,但由于您的文件实际上名为 about.html 位于不同的文件夹中 (/tpl) 服务器需要一些帮助以了解如何将 http://mywebsite.com/about 转换为适当的请求 - 这对您来说是 http://mywebsite.com/#/about 以便它请求路由页面(假设它是 Web 应用程序根文件夹中的默认文档),以便浏览器可以解析并执行执行路由的 JavaScript。资本?

你的请求读起来就像你试图做的是将 "path+file" ("/tpl/about.html") 添加到基础 url ("www.myhost.com").如果是这种情况,那么您需要从当前文档中动态提取主机名,然后将新的 URL 附加到现有的基础上。在javascript中执行以下命令可以获取现有的主机名:

var _location = document.location.toString();
var serverNameIndex = _location.indexOf('/', _location.indexOf('://') + 3);
var serverName = _location.substring(0, serverNameIndex) + '/';

这将 return 一个类似于“http://www.myhost.com/”的字符串,您现在可以将新的 URL 附加到该字符串。所有这些都可以在发送到服务器之前在 javascript 中完成。
如果您只需要服务器名称,而不需要开头的 http 或 https,则将最后一行更改为:

var serverName = _location.substring(_location.indexOf('://') + 3, serverNameIndex) + '/';



让我们分解一下您的代码:

       function loading() {

"location.hash" 是根据最近点击的 URL (www.myhost.home/#about) 设置的。一个基本问题是,这是您想要的操作,还是要从 html 中为 onClick 操作传递一个值?看来这对您来说是一种更有效的方法。

            var a = $.inArray(location.hash, routes),
                template = urls[a];

var a 将被设置为 -1 或 "location.hash" 在 "routes array. If location.hash does not exist in routes, then a==-1 and the script will fail, because you're setting template = urls[-1]. You may want to move setting template to inside the "else" 语句中的位置。

           if (a === -1) {
                location.hash = root;
                $("#view").load(urls[0]);
            }
            else {yada yada yada
            }

您可以在 html 中使用类似于以下的序列:

<a onclick="loading('#about')">Go to About Page</a>

我已经根据您的答案进行了处理,并且构建了以下 路由器。唯一的问题是它仍然使用 location.hash

(function() {
    var Router = {
        root: '#/',
        routes: [],
        urls: [],
        titles: [],
        add: function(thePath, theUrl, theTitle) {
            this.routes.push(thePath);
            this.urls.push(theUrl);
            this.titles.push(theTitle);
        },
        navigate: function() {
            var routes = this.routes,
                urls = this.urls,
                root = this.root;

            function loading() {
                var a = $.inArray(location.hash, routes),
                    template = urls[a];
                if (a === -1) {
                    location.hash = root;
                    $("#view").load(urls[0]);
                }
                else {
                    $("#view").load(template);
                    if (a === 0) {
                        window.scrollTo(0, 0);
                    }
                    else {
                        window.scrollTo(0, 90);
                    }
                }
            }
            window.onload = loading;
            window.onhashchange = loading;
        }
    };
    Router.add("#/", "tpl/home.html", "Home Page");
    Router.add("#/about", "tpl/about.html", "About Page");
    Router.add("#/licence", "tpl/licence.html", "MIIT Licence");
    Router.add("#/cabala", "tpl/cabala.html", "Cabala Checker");
    Router.add("#/articles/esp", "tpl/article1.html", "ESP");
    Router.add("#/fanfics/the-chupacabra-case", "tpl/article2.html", "The Chupacabra Case");
    Router.navigate();
})();

您可能会对 frontexpress 感兴趣。

我的图书馆解决了你的问题,如下所示:

// Front-end application
const app = frontexpress();

const homeMiddleware = (req, res) => {
  document.querySelector('#view').innerHTML = '<p>This is content of home page</p>';
}

app.get('/', homeMiddleware);

app.get('/home', homeMiddleware);

app.get('/about', (req, res) => {
  document.querySelector('#view').innerHTML = '<p>This is the content of the about page </p>';
}); 

显然,您可以从服务器获取模板文件。 #view 将按如下方式提供:

document.querySelector('#view').innerHTML = res.responseText;

gist

中有更详细的示例