路由

更详细的极端测试Demo

Router默认开启,会自动拦截所有链接的Touch行为,如果希望一个链接走浏览器原生跳转而不使用router,可以在链接上增加 class="external" 或者自定义属性,如 <a href="xxx" external>xxx</a>.

如果需要禁用路由功能,那么可以在 zepto 之后, msui 之前使用 script $.config = {router: false} 来禁用.

如只需禁用部分链接,除了使用external外,还可用自定义动态过滤器 $.config.routerFilter = function($link) {},实参 $link 是当前点击的链接,返回 false 表示不使用路由功能,返回 true 表示进入路由处理,参考初始化,示例如下:

{% highlight js %} $.config = { // 路由功能开关过滤器,返回 false 表示当前点击链接不使用路由 routerFilter: function($link) { // 某个区域的 a 链接不想使用路由功能 if ($link.is('.disable-router a')) { return false; } return true; } }; {% endhighlight js %}

路由功能前提

如果需要使用路由功能,那么页面代码结构上需要满足下面两个条件:

  1. 和之前相比的差异:每个 url 对应的 html 文档, 所有的展示内容都必须放在 div.page-group。 形式可以参考router Demo
  2. html 文档中, 每个可以用来切换显示的块都应该有 page 的 class
也就是说,每个 html 页面的基本结构都应该是下面这样(示例中省略 body 等): {% highlight html %} ...
...
...
... {% endhighlight html %}

内联页面

你可以在同一个HTML文件中内联编写多个页面。每一个页面都是一个 .page 容器,如果有多个页面,则需要用 .page-current 标记出第一次进入的时候应该显示的页面。

每一个 .page 容器都应该有一个全局唯一的id,路由器会使用这个id作为唯一标示,如果没有设置id,可能会导致路由出错。你只需要这样写一个链接就可以跳转到id对应的内联页面 <a href='#{page-id}'>跳转</a>.

{% highlight html %}

路由

返回

路由

这是内联编写的页面,点击左上角的 返回 按钮返回上一页。
{% endhighlight %}

ajax页面

注意: ajax 和 pushState 限制了 ajax 加载的页面只能是同域.

除了内联编写多个页面以外,你还可以通过ajax来加载新页面。通过ajax加载新页面和普通的链接写法没有区别,路由器会自动拦截链接的点击事件,并通过ajax请求加载新的页面。

{% highlight html %}

路由

{% endhighlight %} {% highlight html %}
返回

路由

这是ajax 加载的新页面,点击左上角的 返回 按钮返回上一页。
{% endhighlight %}

后退

我们对后退操作进行了封装,你只需要在任意链接上增加一个 .back 类,点击就会自动返回到上一页(调用 history.back)。

或者你可以通过调用 $.router.back() 来执行返回上一页操作。

{% highlight html %} 返回上一页 {% endhighlight %}

缓存

默认地,对于加载过的页面,只要页面没刷新,那么再次进入该页面时,都会优先读取缓存而不发送网络请求。如果需要强制请求,可以用下面两种方式:

JS方法

你可以通过调用 $.router.load(url, ignoreCache) 来加载一个页面,参数url既可以是一个ajax页面的地址,也可以是一个内联页面的id.

{% highlight js %} $.router.load("/detail"); //加载ajax页面 $.router.load("#about"); //加载内联页面 // ignoreCache 是加载一个新页面时是否忽略缓存而发网络请求,默认是 false,表示使用缓存,可以设为 true 来忽略缓存 $.router.load('/detail', true); {% endhighlight %}

事件

从一个页面准备开始加载,到执行完加载动画,会按顺序触发以下事件:

事件 说明
pageLoadStart 发送Ajax之前触发
pageLoadCancel 取消了正在发送的ajax请求
pageLoadError Ajax 请求失败
pageLoadComplete Ajax 请求结束,无论是成功还是失败
pageAnimationStart 新页面的DOM插入当前页面之后,动画执行之前
pageAnimationEnd 新页面动画执行完毕
beforePageRemove 加载新的页面,动画切换完成后,移除旧的 document 前发送,事件回调函数参数是event, $pageContainer,其中$pageContainer.page-group(注:在 window 上触发,且内联 page 的切换不会触发此事件)
pageRemoved 加载新的页面,动画切换完成后,移除旧的 document 后发送(注:在 window 上触发,且内联 page 的切换不会触发此事件)
beforePageSwitch page 切换前触发,该事件在 pageAnimationStart 前,beforePageSwitch 之后会做一些额外的处理才触发 pageAnimationStart
pageInit 新页面中的组件初始化完毕

其中 pageLoad* 事件是在 window 上触发,其他都是在 .page 元素上触发。为了性能考虑,最好通过 document 代理监听。如果是内联页面,则没有前面的四个 pageLoad* 事件。

你可以这样监听事件:

{% highlight js %} $(document).on("pageInit", "#page-index", function(e, pageId, $page) {}); $(document).on("pageInit", function(e, pageId, $page) { if(pageId == "pageIndex") {} }); {% endhighlight %}