路由 - SUI 移动开发UI库

返回介绍

路由

发布于 2017-06-10 字数 7599 浏览 1525 评论 0

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 表示进入路由处理,参考初始化,示例如下:

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

        return true;
    }
};

路由功能前提

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

  • 和之前相比的差异:每个 url 对应的 html 文档, 所有的展示内容都必须放在 div.page-group。 形式可以参考router Demo
  • html 文档中, 每个可以用来切换显示的块都应该有 page 的 class

也就是说,每个 html 页面的基本结构都应该是下面这样(示例中省略 body 等):

...
<div class="page-group">
    <div class="page">...</div>
    <div class="page">...</div>

    <!-- 如果有 popup -->
    <div class="popup popup-about">...</div>
</div>
...

内联页面

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

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

<div class="page page-current" id='router'>
  <header class="bar bar-nav">
    <h1 class='title'>路由</h1>
  </header>
  <div class="content">
    <div class="content-block">
      <ul>
        <li><a href="/docs-demos/router2">ajax加载新页面</a></li>
        <li><a href="#router3">内联的新页面</a></li>
      </ul>
    </div>
  </div>
</div>

<div class="page" id='router3'>
  <header class="bar bar-nav">
    <a class="button button-link button-nav pull-left back" href="/docs-demos/router">
      <span class="icon icon-left"></span>
      返回
    </a>
    <h1 class='title'>路由</h1>
  </header>
  <div class="content">
    <div class="content-block">
      这是内联编写的页面,点击左上角的 <a href="#" class='back'>返回</a> 按钮返回上一页。
    </div>
  </div>
</div>

Ajax页面

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

<!-- page 1 -->
<div class="page page-current" id='router'>
  <header class="bar bar-nav">
    <h1 class='title'>路由</h1>
  </header>
  <div class="content">
    <div class="content-block">
      <ul>
        <li><a href="/docs-demos/router2">ajax加载新页面</a></li>
      </ul>
    </div>
  </div>
</div>
<!-- page 2 -->
<div class="page" id='router2'>
  <header class="bar bar-nav">
    <a class="button button-link button-nav pull-left back" href="/docs-demos/router">
      <span class="icon icon-left"></span>
      返回
    </a>
    <h1 class='title'>路由</h1>
  </header>
  <div class="content">
    <div class="content-block">
      这是ajax 加载的新页面,点击左上角的 <a href="#" class='back'>返回</a> 按钮返回上一页。
    </div>
  </div>
</div>

后退

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

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

<a class="button button-link button-nav pull-left back" href="/docs-demos/router">返回上一页</a>

缓存

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

  • 在 a 链接上添加 data-no-cache="true" 属性来标明点击该链接时不使用缓存,如:<a href="/detail" data-no-cache="true">no cache</a>
  • 使用 js 方法 load 来加载时,把可选的参数 ignoreCache 设为 true,如:$.router.load('/detail', true)

JS方法

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

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

事件

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

事件 说明
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* 事件,你可以这样监听事件:

$(document).on("pageInit", "#page-index", function(e, pageId, $page) {});
<!--或者-->
$(document).on("pageInit", function(e, pageId, $page) {
  if(pageId == "pageIndex") {}
});

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

支持 Markdown 语法,需要帮助?

目前还没有任何评论,快来抢沙发吧!