20行JavaScript代码实现Router

上周我看到一篇 20行代码实现模板引擎,这是受John Resig’s post on the same topic启发的。我发现他们是如此简单,有趣同时也激发我产生一个20行代码实现客户端Router的想法。

开始创建一个router

首先我们需要一个html模板:

<!DOCTYPE html>  
<html>  
<head>  
  <meta charset="utf-8">
  <title>Building a router</title>
  <script>
    // Put John's template engine code here...
  </script>
</head>  
<body>

</body>  
</html>  

在模板中我使用带有 __type="text/html"__标识的script的标签,以防止浏览器来渲染它们里面的内容,就像我们想的,我把它们放到了现有script标签的后面。

<script type="text/html" id="home">  
  <h1>Router FTW!</h1>
</script>  
<script type="text/html" id="template1">  
  <h1>Page 1: <%= greeting %></h1>
  <p><%= moreText %></p>
</script>  
<script type="text/html" id="template2">  
  <h1>Page 2: <%= heading %></h1>
  <p>Lorem ipsum...</p>
</script>

就像我们看的一样,它们是如此的基础,那是因为我们这篇文章专注于路由部门。

Hash URL’s

为了实现路由我将使用URL’s,就是在#后面的一串东西,例如:http://example.com/#/our/url/here,我可以通过使用HTML5 History AP来实现,但是我会在下次来使用它。

处理route变化

页面加载完之后通过onhashchange事件来处理路由变化同时使用onload事件来处理页面加载之后对应的处理。

路由注册方法

我们开始构建路由注册方法:

// A hash to store our routes:
var routes = {};  
// The route registering function:
function route (path, templateId, controller) {  
  routes[path] = {templateId: templateId, controller: controller};
}

注册路由

现在我们可以创建新的路由,注意我模仿了AngularJs的控制器定义方式:

route('/', 'home', function () {});  
route('/page1', 'template1', function () {  
    this.greeting = 'Hello world!';
    this.moreText = 'Bacon ipsum...';
});
route('/page2', 'template2', function () {  
    this.heading = 'I\'m page two!';
});

但是依旧什么也没发生,因为我们还没有处理路由的方法……

真是的路由处理方法

我们创建了路由处理方法,但是我们依旧不知道在哪里渲染我们的内容,现在我设置了一个id为view的元素来容纳我们的内容:

var el = null;  
function router () {  
    // Lazy load view element:
    el = el || document.getElementById('view');
    // Current route url (getting rid of '#' in hash as well):
    var url = location.hash.slice(1) || '/';
    // Get route by url:
    var route = routes[url];
    // Do we have both a view and a route?
    if (el && route.controller) {
        // Render route template with John Resig's template engine:
        el.innerHTML = tmpl(route.templateId, new route.controller());
    }
}
// Listen on hash change:
window.addEventListener('hashchange', router);  
// Listen on page load:
window.addEventListener('load', router);  

万事俱备,我们来测试一下!

测试第一版本

首先我们在页面添加一些可以导航的链接,来触发我们不同的路由:

<ul>
    <li><a href="#">Home</a></li>
    <li><a href="#/page1">Page 1</a></li>
    <li><a href="#/page2">Page 2</a></li>
  </ul>
  <div id="view"></div>

第一版本的代码在这里

保存完整的代码并在高级浏览器中打开,你回发现:

Router FTW!

同时那些可以导航的链接一样可以使用,你可以在浏览器中直接输入指定路由,比如:”path/to/your/router.html#/page1”同时你会看到内容”page1”。

原文:A Javascript router in 20 lines

分享到: