## 路由

Mobilebone 是基于 HTML5 history API 实现的路由控制。

### 原理

Mobilebone 的路由遵循和浏览器原生的 URL 历史记录一样的原理，只是传统的 URL 历史记录变化往往伴随着页面的刷新或跳转，而 Mobilebone 框架下的 URL 历史变化页面是无刷新的。

例如，页面中有一个链接元素：

    <a href="router.html" class="nav-a" data-mask>路由</a>

在原生状态下，点击上面的链接，页面会跳转到 `router.html` 这个页面，同时 URL 会增加 `router.html` 的历史记录；而在 Mobilebone 框架下，点击上面的链接，页面也会跳转到 `router.html` 这个页面，但是跳转过程是无刷新的，同时 URL 也会增加一条标示 `router.html` 的历史记录。

其底层实现原理如下：

1. 阻止 `<a>` 元素的默认行为（不会跳转）；
2. 请求 `<a>` 元素 `href` 属性指向的页面的内容并显示；
3. 增加一条历史记录，通过执行下面的代码：

       history.pushState(null, document.title, '#&router.html');

由于采用浏览器一致的 URL 历史记录，因此，用户点击浏览器原生的后退按钮，或者执行 `history.go(-1)`，会自动回到上一个页面的 URL 地址，此时 Mobilebone 可以检测到这种变化（会触发 `popstate` 事件），然后显示对应的页面内容。

Mobilebone 中的路由跳转基本上就围绕上面两种场景展开，新场景新增历史记录，回到过去则回到之前的历史记录。

### 语法

Mobilebone 采用 hash 识别路由信息。其语法格式为：

    #&[<custom-ident> | <url>]

例如，当前页面的 URL 地址为：

    /docs/guide/#&router.html

其中，`#&router.html` 就是 Mobilebone 路由信息，表示当前页面显示的是 `router.html` 页面的内容，当用户刷新页面的时候，Mobilebone 会基于 `#&router.html` 重新请求 `router.html` 页面的内容。

路由信息还可以是 `div.page` 元素上的 `id` 属性值，例如：

    <a href="#nextPage">下一个页面</a>

如果页面中有 `id` 为 `nextPage` 的元素，则点击上面链接，URL 地址的 hash 信息就会变成 `#&nextPage`。

其他：`#&`后面的 `&` 符号的作用是防止 URL 锚定，因为类似包含 `#nextPage` 的 URL 地址会触发 `id` 为`nextPage` 的元素的滚动定位（如果 `display` 不是 `none` ），会影响过场效果的执行。

### 设置

- 在 Mobilebone 中，页面之间的路由跳转不是通过 JavaScript 进行配置的，而是在 HTML 中基于原生属性进行设置的，主要通过 `<a>` 元素的 `href` 属性设置。例如：

      <a href="#nextPage">下一个页面</a>
      <a href="./router.html">路由页面</a>

  如果希望点击上面的链接 URL 地址不会发生变化，也就是不发生任何 URL 记录，可以设置 `data-history="false"`，例如：

      <a href="./router.html" data-history="false">路由页面</a>

- `<form>` 元素的 `action` 属性值也可以作为路由地址，不过目前业界的前端开发都不太感冒基于 `<form>` 元素数据交互，因此，Mobilebone 的这个能力很少被用到。

- Mobilebone 底层的 `Mobilebone.transition(pageInto[, pageOut][[, back], options])` 方法也可以用来进行路由设置，`options` 支持一个名为 `id` 的可选参数，当 `pageInto` 元素没有 `id` 的时候，会使用 `options.id` 作为路由地址。

以上就是 Mobilebone 框架中所有的路由设置的方法。

### 方向

Mobilebone 中的过场是有方向性的，默认是左右过场，右进左退。

当从 A 页面过渡到 B 页面的时候，B页面是从右侧进入，还是从左侧回退，Mobilebone 有一套自己的计算规则。

1. 各个过场DOM元素在文档流中的前后位置，B 页面在 A 页面的前面，则过场方法是反方向；
2. 来源页面是否和当前目标页面一致，如果一致，Mobilebone 会执行 `history.back()` 进行返回；
3. 临时记录中是否有目标页面元素，如果存在，则过场方法是反方向；

以上这套规则能够保证大多数场景下，页面间的过场方向是自然的，是符合预期的，用户是无需关心细节的。

但是实际应用场景千变万化，以上这套规则并不是万能的，例如，Mobilebone 自己内部的历史记录是临时的，页面刷新之后（此操作通常不会发生，但无法避免），记录就会丢弃，此时方向的判断可能就和用户的预期发生冲突。

所以，如果点击某个链接或者按钮一定是反方向的，则建议使用 `data-rel="back"` 进行明确的方向设置。例如：

    <a href="#pageBack" data-rel="back">返回到pageBack页面</a>

或者是纯粹的返回上一条历史记录：

    <a href="javascript:" data-rel="back">返回到上一页</a>

另外，Mobilebone 还支持设置强制过场方向是正方向，语法是 `data-rel="go"`。

发现错误？想参与编辑？在 GitHub 上编辑此页！