mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-13 22:30:37 +08:00
commit
335300228a
@ -1,7 +1,6 @@
|
||||
Translating by qhwdw
|
||||
JavaScript Router
|
||||
JavaScript 路由器
|
||||
======
|
||||
There are a lot of frameworks/libraries to build single page applications, but I wanted something more minimal. I’ve come with a solution and I just wanted to share it 🙂
|
||||
构建单页面应用有许多的框架/库,但是我希望它们能少一些。我有一个解决方案,我想共享给大家。🙂
|
||||
```
|
||||
class Router {
|
||||
constructor() {
|
||||
@ -52,13 +51,13 @@ console.log(router.exec('/foo')) // not found page
|
||||
|
||||
```
|
||||
|
||||
To use it you add handlers for a URL pattern. This pattern can be a simple string or a regular expression. Using a string will match exactly that, but a regular expression allows you to do fancy things like capture parts from the URL as seen with the user page or match any URL as seen with the not found page.
|
||||
使用它为一个 URL 模式添加处理程序。这个模式可能是一个简单的字符串或一个正则表达式。使用一个字符串将精确匹配它,但是如果使用一个正则表达式将允许你做一些更复杂的事情,比如,从用户页面上看到的 URL 中获取其中的一部分,或者匹配任何没有找到页面的 URL。
|
||||
|
||||
I’ll explain what does that `exec` method… As I said, the URL pattern can be a string or a regular expression, so it first checks for a string. In case the pattern is equal to the given pathname, it returns the execution of the handler. If it is a regular expression, we do a match with the given pathname. In case it matches, it returns the execution of the handler passing to it the captured parameters.
|
||||
我将详细解释这个 `exec` 方法 … 正如我前面说的,URL 模式既有可能是一个字符串,也有可能是一个正则表达式,因此,我首先来检查它是否是一个字符串。如果模式与给定的路径名相同,它返回运行处理程序。如果是一个正则表达式,我们与给定的路径名进行匹配。如果匹配成功,它将获取的参数传递给处理程序,并返回运行这个处理程序。
|
||||
|
||||
### Working Example
|
||||
### 工作示例
|
||||
|
||||
That example just logs to the console. Let’s try to integrate it to a page and see something.
|
||||
那个例子正好记录到了控制台。我们尝试将它整合到一个页面,看看它是什么样的。
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
@ -80,18 +79,18 @@ That example just logs to the console. Let’s try to integrate it to a page and
|
||||
|
||||
```
|
||||
|
||||
This is the `index.html`. For single page applications, you must do special work on the server side because all unknown paths should return this `index.html`. For development, I’m using an npm tool called [serve][1]. This tool is to serve static content. With the flag `-s`/`--single` you can serve single page applications.
|
||||
这是 `index.html`。对于单页面应用程序来说,你必须在服务器侧做一个特别的工作,因为所有未知的路径都将返回这个 `index.html`。在开发时,我们使用了一个 npm 工具调用了 [serve][1]。这个工具去提供静态内容。使用标志 `-s`/`--single`,你可以提供单页面应用程序。
|
||||
|
||||
With [Node.js][2] and npm (comes with Node) installed, run:
|
||||
使用 [Node.js][2] 和安装的 npm(它与 Node 一起安装),运行:
|
||||
```
|
||||
npm i -g serve
|
||||
serve -s
|
||||
|
||||
```
|
||||
|
||||
That HTML file loads the script `main.js` as a module. It has a simple `<header>` and a `<main>` element in which we’ll render the corresponding page.
|
||||
那个 HTML 文件将脚本 `main.js` 加载为一个模块。在我们渲染的相关页面中,它有一个简单的 `<header>` 和一个 `<main>` 元素。
|
||||
|
||||
Inside the `main.js` file:
|
||||
在 `main.js` 文件中:
|
||||
```
|
||||
const main = document.querySelector('main')
|
||||
const result = router.exec(location.pathname)
|
||||
@ -99,17 +98,17 @@ main.innerHTML = result
|
||||
|
||||
```
|
||||
|
||||
We call `router.exec()` passing the current pathname and setting the result as HTML in the main element.
|
||||
我们调用传递了当前路径名为参数的 `router.exec()`,然后将 `result` 设置为 main 中的 HTML 元素。
|
||||
|
||||
If you go to localhost and play with it you’ll see that it works, but not as you expect from a SPA. Single page applications shouldn’t refresh when you click on links.
|
||||
如果你去 `localhost` 并运行它,你将看到它能够正常工作,但不是预期中的来自一个单页面应用程序。当你点击链接时,单页面应用程序将不会被刷新。
|
||||
|
||||
We’ll have to attach event listeners to each anchor link click, prevent the default behavior and do the correct rendering. Because a single page application is something dynamic, you expect creating anchor links on the fly so to add the event listeners I’ll use a technique called [event delegation][3].
|
||||
我们将在每个点击的链接的锚点上附加事件监听器,防止出现缺省行为,并做出正确的渲染。因为一个单页面应用程序是一个动态的东西,你预期要创建的锚点链接是动态的,因此要添加事件监听器,我使用的是一个叫 [事件委托][3] 的方法。
|
||||
|
||||
I’ll attach a click event listener to the whole document and check if that click was on an anchor link (or inside one).
|
||||
我给整个文档附加一个点击事件监听器,然后去检查在锚点上(或内部)是否有点击事件。
|
||||
|
||||
In the `Router` class I’ll have a method that will register a callback that will run for every time we click on a link or a “popstate” event occurs. The popstate event is dispatched every time you use the browser back or forward buttons.
|
||||
在 `Router` 类中,我有一个注册回调的方法,在我们每次点击一个链接或者一个 “popstate” 事件发生时,这个方法将被运行。每次你使用浏览器的返回或者前进按钮时,`popstate` 事件将被发送。
|
||||
|
||||
To the callback we’ll pass that same `router.exec(location.pathname)` for convenience.
|
||||
为了方便其见,我们给回调传递与 `router.exec(location.pathname)` 相同的参数。
|
||||
```class Router {
|
||||
// ...
|
||||
install(callback) {
|
||||
@ -149,9 +148,9 @@ To the callback we’ll pass that same `router.exec(location.pathname)` for conv
|
||||
}
|
||||
```
|
||||
|
||||
For link clicks, besides calling the callback, we update the URL with `history.pushState()`.
|
||||
对于链接的点击事件,除调用了回调之外,我们还使用 `history.pushState()` 去更新 URL。
|
||||
|
||||
We’ll move that previous render we did in the main element into the install callback.
|
||||
我们将前面的 `main` 元素中的渲染移动到 `install` 回调中。
|
||||
```
|
||||
router.install(result => {
|
||||
main.innerHTML = result
|
||||
@ -161,7 +160,7 @@ router.install(result => {
|
||||
|
||||
#### DOM
|
||||
|
||||
Those handlers you pass to the router doesn’t need to return a `string`. If you need more power you can return actual DOM. Ex:
|
||||
你传递给路由器的这些处理程序并不需要返回一个 `string`。如果你需要更多的东西,你可以返回实际的 DOM。如:
|
||||
```
|
||||
const homeTmpl = document.createElement('template')
|
||||
homeTmpl.innerHTML = `
|
||||
@ -178,7 +177,7 @@ function homePage() {
|
||||
|
||||
```
|
||||
|
||||
And now in the install callback you can check if the result is a `string` or a `Node`.
|
||||
现在,在 `install` 回调中,你可以去检查 `result` 是一个 `string` 还是一个 `Node`。
|
||||
```
|
||||
router.install(result => {
|
||||
if (typeof result === 'string') {
|
||||
@ -190,9 +189,9 @@ router.install(result => {
|
||||
})
|
||||
```
|
||||
|
||||
That will cover the basic features. I wanted to share this because I’ll use this router in next blog posts.
|
||||
这些就是基本的功能。我希望将它共享出来,因为我将在下篇文章中使用到这个路由器。
|
||||
|
||||
I’ve published it as an [npm package][4].
|
||||
我已经以一个 [npm 包][4] 的形式将它发布了。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -200,7 +199,7 @@ via: https://nicolasparada.netlify.com/posts/js-router/
|
||||
|
||||
作者:[Nicolás Parada][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
译者:[qhwdw](https://github.com/qhwdw)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
Loading…
Reference in New Issue
Block a user