mobilebone.js-mobile移动web APP单页切换骨架

标签: js实例 mobile相关 animationend animationstart fastclick | 发表时间:2014-10-31 05:34 | 作者:张 鑫旭
出处:http://www.zhangxinxu.com/wordpress

by zhangxinxu from http://www.zhangxinxu.com
本文地址: http://www.zhangxinxu.com/wordpress/?p=4381

一、mobilebone.js吹牛不打草稿

mobilebone.js是鄙人2014下半年个人开源项目代表作。

先容我吹嘘一番,反正吹牛又不要交税。

  • 轻便体积小
  • 原生无依赖
  • 插件可扩展
  • 设计无限制
  • 动效可定制
  • 动静两相宜
  • 能进亦能退
  • 桌面也兼修

一句话功能简介
跟传统网页浏览的差别仅仅在于无刷新!

例如,我们浏览首页,首页上有个如下HTML链接:

<a href="mocamoca.html">摩擦摩擦</a>

在传统页面,页面会刷新跳转至 mocamoca.html, 但是,引入 mobilebone.js后,就是无属性滑动到 mocamoca.html页面。

OK,我特意用手机拍手机拍了段视频给大家感受下(视频中的页面为项目中的测试页面)(舍不得买iPhone, 测试机为Android)(优酷上传太慢40K/s果断投奔爱奇艺了2M/s):

当然,你也可以打开自己的手机浏览器、或者微信扫描下面二维码,体验同时顺便帮忙众测下,可以评论或者去Github项目issues( https://github.com/zhangxinxu/mobilebone/issues)反馈给类问题(前后两个图分别是develop和master两个分支的测试页):

develop分支的测试页地址 项目测试页面二维码

如果你是在手机浏览器访问本页面,试试直接 点击这里感受一番。

二、mobilebone.js项目、资源以及八卦

Mobilebone项目已经发布到Github上了,项目地址为: https://github.com/zhangxinxu/mobilebone

如果你觉得此项目很赞,欢迎star, 如果你想参与建设,欢迎fork!

为什么叫Mobilebone?
1. 顾名思意,移动骨头。 mobilebone.js也确实人如其名,只做一件事情,移动端单页切换,所以 mobilebone.js很轻便,也很灵活,也没什么限制,反而铸就了其强大。
2. 以前的一些个人项目,会加上zxx之类的标示,甚觉得格局太低了。所以,命名为Mobilebone这么大气的名词,就是希望可以冲出中国,走向世界。万一火了呢,就可以跟Backbone平起平坐啦!
3. 我特意百度谷歌之,恩,没人用这个名词。Github上也没有类似名字的项目,于是就是它的,独一无二的!

为何想到做Mobilebone?
早在11年移动刚兴起的时候,我就折腾过 jQuery Mobile以及Phonegap. 好吧,也就是折腾过,后来很快就把jQuery Mobile给丢弃了,主要有两点:一是重,而是UI限制太大,只适合个人项目!但是,其switch切换是挺值得借鉴的。

上个月,应该是上上个月,游击了一个手Q的项目,做重构稿的时候,写了个单页切换方法,主要是为了重构稿交互演示。结果被开发直接拿去用了,于是问题来了,此切换方法并没有添加Ajax处理,也没有history路由处理。以至于最后的实现代码不醇厚-用人话表示就是“乱”。此时,我意识到,应该可以写个专门负责单页切换的JS组件。加上自己多年的相关积累,Android2.3这些版本不需要兼容,我觉得时机很成熟了。

于是,前后一个多月,利用业余时间,编写、测试与反复优化、细节调整,终于发布了这个个人项目。我会积极在厂内外推广,农村和城市齐包围,万一真火了呢!

Mobilebone适用场景
类原生APP的过场体验,适用于这些场景:
1. Phonegap等类似跨移动开发平台,其静态页面都是index.html, 单页面,因此,需要跟原生一样的过场体验。自己帮设计师实现iOS原型时候需要。
2. Hybird app开发,原生APP内嵌web APP, 为了两者体验一致,不至于交互太唐突,也需要无刷新过场效果。例如,上面提到的那个手Q项目。
3. 就算是纯粹的移动web APP, 使用无刷新模式也不失为一种不错的选型策略。
4. 一些高大上的在线幻灯片演示……等

Mobilebone兼容性
mobilebone.js基于ES5编写,应用了部分HTML特性,原生JS,不依赖任何其他JS框架,不支持Android 2.3及其以下版本,不支持IE6-IE9. 如果这些搓浏览器引入 mobilebone.js, 不会报错,不影响正常使用。

三、mobilebone.js基本使用

首先,引入相关的CSS和JS:

<link rel="stylesheet" href="mobilebone.css">
<script src="mobilebone.js"></script>

此时,就会有一个全局的Mobilebone对象,包含一些属性与方法。

然后,HTML结构有一定的规则。

body
  page
  page
  page

上面规则是什么意思呢?

我们可以看下 mobilebone.css结构相关的CSS代码:
结构相关的CSS代码

传统网页, body基本上就是页面代名词,滚动条多半也是 body标签产生。但是,一个页面貌似只能一个 body,所以,单页switch切换主体就不能是 body元素,于是,降级,以 body子元素 page作为每个页面的框架结构,担当 body角色。于是,偶们看到的切换效果,就是 page间的相互纠缠效果。

这种HTML结构与CSS布局的另外一个好处就是,可以方便实现兼容的头部底部固定效果( position:fixed效果问题依然多多)。例如下面这个 base-slide测试页面的HTML结构:

<body>
  <div id="pageHome" class="page out"></div>
  <div id="page1" class="page out"></div>
  <div id="page2" class="page out"></div>
  <div id="page3" class="page out"></div>
</body>

.page对应的元素就是我们的每一个页面,我们可以在此 div中尽情书写我们的设计布局。一般而言,要在 page元素内部再嵌套一个 content元素,主要为了实现滚动。如果使用 iScroll滚动, 无需定高;如果原生滚动, content元素需要有特定高度值。

然后,什么也不用做,页面就能进入无刷新切换模式,超赞的有木有。

如果你想做一些设置,直接在引入 mobilebone.js之后设置就好了。例如下面 Mobilebone.captureLink的设置:

<script src="mobilebone.js"></script>
<script>
Mobilebone.captureLink = false;
</script>

因为,Mobilebone的默认初始化在DOMContentLoaded之后,因此不需要担心顺序问题。不过,如果你是页面 load完毕后再以模块化方式(如seajs~)加载 mobilebone.js,需要手动初始化一下,此时,就要注意顺序,初始化在参数设置的前面,如下:

Mobilebone.captureLink = false;
Mobilebone.init();  // 初始化

记住,一个页面只能初始化一次,以免文档事件重复绑定。

四、mobilebone.js与基本切换

所谓基本切换,指的是无请求,无延迟的即时切换。表现为:每个page在第1次加载完毕后,就已经存在页面,所谓的切换仅仅是这些page元素的位置变化。

就好比我们使用PowerPoint文件,每次打开一个屁屁踢幻灯片文件,一个一个幻灯片页面实际都是已经存在的,我们的浏览,其实都是幻灯片页面的位置变化,这就是基本切换。

在DOM层面,只有一种情况会触发基本切换, href值为锚链的 a元素。例如:

<a href="#pageId">

于是,当我们 tap/click这个 a元素的时候,Mobilebone会自动寻找 idpageId的页面,如果此页面存在,则发生切换动画;如果没有该页面元素,没有任何反应,死链。

若有兴趣,可以 轻戳这里访问感受基本切换效果。

相反的过场方向
动画的方向不可能都是从右往左的,例如,返回,显然是需要刚进入动画相反,符合正常认知。要实现,很简单,通过添加 data-rel="back"就可以了,例如:

<a href="#pageHome" data-rel="back">返回</a>

此时,元素过新增一个类名 reverse反方向运动。

然而,有时候,我们无法确定动画的方向,例如,固定在底部的导航,如果导航3从导航2过来,自然是正方向;但如果是从导航4过来,则要反方向。 data-rel该如何设置呢?

哈,使用 "auto"即可,如下:

<a href="#pageHome" data-rel="auto">前进还是后退?</a>

Mobilebone会自动判别页面在舞台上的位置,智能识别运动方向。浏览器的历史记录前进与后退也是采用的 "auto"判别机制。

此应用可参考 头尾固定测试页面test/fixed-header-footer/index.html.

data-rel控制访问同样适用于下面的Ajax切换。

五、mobilebone.js与Ajax切换

实际项目,可能有10+个页面,显然是不可能全部一次性载入的,又大又慢,对于流量如金的移动页面,是损耗也是浪费。所以,页面内容还是要一个一个加载实在,这就需要Ajax切换了。

Ajax加载并切换的实现很简单,你不需要做任何操作,就跟传统的web页面一样就好,使用 href指向要加载的页面地址,例如:

<a href="ajax.html">

此时,当我们 tap/click这个 a元素的时候,Mobilebone会以Ajax的形式请求 ajax.html这个页面,返回的数据会封装成 page页面,并以指定的过场动画载入。是不是简单得有点过分了?没错,所以下面要加点料。

1. Ajax请求参数
既然是Ajax请求,自然少不了请求参数了。Mobilebone中的Ajax借用了jQuery中 $.ajax()方法的参数命名,主要如下:

var defaults = {
    url: "",
    dataType: "",
    data: {},
    timeout: 10000,
    async: true,
    username: "",
    password: "",
    success: function() {},
    error: function() {},
    complete: function() {}	
}

<a>元素传参策略
对于元素,我们是直接通过属性设置传参。有两种支持的形式,分别为 data-*data-params.

  • data-*是指需要传递参数,把参数名替换这里的星号(不区分大小写),并赋予参数值。例如:
    <a href="ajax.html" data-timeout="30000">

    就是设置请求超时时间为30秒。

    不过仍有两个注意点:

    1. 如果 href值正常,则 data-url地址会被忽略,依然使用 href对应地址作为Ajax请求地址。
    2. 没有 data-data, 而是 data-formdata. 例如:
      <a href="ajax.html" data-formdata="c=1&d=1">
  • data-params值则是查询序列串。因为如果需要自定义的参数过多,标签上就会有很多 data-*属性,略啰嗦。于是,可以以查询序列串的形式作为 data-params的值,例如:
    <a href="ajax.html" data-params="datatype=json&timeout=20000&success=fun_success">

    有人可能会疑问,如果存在 data-*data-params冲突情况怎么办?哈, data-*优先级大于 data-params. 所以,类似下面代码,则最后请求超时时间为 30s, data-params中的 20s会被忽略。

    <a href="ajax.html" data-timeout="30000" data-params="datatype=json&timeout=20000&success=fun_success">

    还有一点,不支持 data参数的序列化使用,请使用上面的 data-formdata. 有兴趣可以 轻戳这里看下如何使用的。

Ajax回调函数
Ajax回调函数有三个,跟jQuery的Ajax请求一样,分别是 success, error, 与 complete. 分别表示请求成功,请求失败与请求完成(包含部分失败情况)。注意,下面开始高能了:

<a href="ajax.html" data-success="globalObject.fun.xxx_ajax_success">

上面的传参就是上面提到的 data-*策略,类似,错误回调,可以使用 data-error或者 data-params="error=xxx". 下面问题来了, globalObject.fun.xxx_ajax_success表示什么意思?

如果使用了上面代码,只要不是估计瞎搞,在JS的世界里肯定有下面这位兄弟:

window.globalObject = {
    fun: {
        xxx_ajax_success: function() {}
    }
};

意思就是,当请求成功的时候,执行全局对象 globalObject下的子对象 fun下面的 xxx_ajax_success这个方法。最后一个字符串段一定是方法名,否则是不会有任何执行的。例如:

<a href="ajax.html" data-success="xxx_ajax_success">

则表示请求成功的时候,调用全局方法 xxx_ajax_success.

  • 成功回调函数支持两个参数, success(response, status), 其中 response表示Ajax请求返回的内容,HTML或者JSON. status这个参数其实没啥用,返回成功的状态码。其中,默认的 this上下文是Ajax执行的完整参数们,是个对象。结构类似本小节展示的 defaults对象。
  • 错误回调也支持两个参数, error(xhr, status), 其中 xhr是发送的请求对象, status跟上面一样意思,就不多说了。其中,默认的 this上下文是Ajax执行的完整参数们,是个对象。与其他两个回调有一个很大的不同,多了个 message属性,告知了错误原因,如,网络掉线、超时或是是JSON解析异常等。
  • 完成回调也支持两个参数, complete(xhr, status), 其中 xhr是发送的请求对象, status跟上面一样意思,就不多说了。其中,默认的 this上下文是Ajax执行的完整参数们。

字符串类型返回值
默认返回的是字符串,会按照HTML字符串处理。

例如,我们请求 ajax.html页面,该页面最好是完整的 body > page结构。因为,就算页面JS挂掉,无法阻止默认链接行为,发生跳转,也不会影响可用性。但是,如果请求的是个动态页面,直接返回的是干净的HTML代码,如果没有 page元素,则不能含有 html以及 body标签。

因为Mobilebone会寻找返回HTML中的 page元素作为页面载入;如果没有,则会将返回的所有HTML封装在自己创建的 page中。简言之,要么返回“完整HTML页面代码”, 要么返回“干净的HTML片段代码”。

2. JSON类型的请求
由于某些团队的中间层还没成熟,前后端半分离状态,导致请求得到的数据只能是JSON数据。虽然个人建议是后台那边使用某些框架基直接吐HTML返回,但现实是骨感的。不过不要太多担心,Mobilebone是有考虑过这种情况的,其暴露了一个方法名为 Mobilebone.jsonHandle(json), 专门用来处理JSON数据源,需要返回渲染的HTML视图代码或者直接就是 page元素。

支持一个参数 json, 此参数必须,为Ajax请求返回的JSON数据。于是,你就可以在此处理方法中套用模板,吐出页面完整HTML. Mobilebone会自动根据吐出的内容生成页面,并以过场动画形式载入。

需要注意的是, Mobilebone.jsonHandle是个全局的唯一的方法,所以,如果页面有多个JSON渲染,请使用返回的JSON数据的 id或其他标志量做区分,精准返回HTML数据(也可以自己返回页面-不多见)(可参考测试页面中 Backbone的例子)。

下面是JSON测试页面的例子代码:

Mobilebone.jsonHandle = function(json) {
    var page = document.createElement("div");
    page.className = "page out";
    page.setAttribute("data-title", json.title);
    page.innerHTML = json.html;
    return page;
};

简单示意,不要太认真。若有兴趣,可以 轻戳这里访问体验下。

更好的JSON包括HTML加载建议
虽然Mobilebone提供了直接请求JSON数据的方法,并提供了视图渲染接口。但是,以我个人经验,对于实际开发,这种实现策略是不推荐的。我认为更好的实现方法应该是这样的。页面骨架,也就是page主体,也就是一个空 div默认就载入,然后所有的切换都是基本切换,而不是Ajax切换。在切换即将开始的时候(回调),您就可以使用自己,例如Zepto的Ajax方法去请求你需要的JSON数据,做你任何想做的事情,完全没有Mobilebone的限制。

页面slide是有时间的,350ms, 这个时间点很可就就完成呈现了最终的页面。于是,我们看到的就是,一点击,页面slide,slide结束,内容呈现。哇哦哦~~操作感不要太流畅哦!而且技术上更可控,因为数据请求、处理与Mobilebone完全解耦。

当然,如果就是个原型页面、简单的静态页面,或者是不喜JS的小伙伴,依赖Mobilebone的Ajax整体请求与呈现策略显然是最好的选择,因为,你什么都不需要做~

3. 请求页面的缓存机制
默认情况下,Ajax请求的页面,如果之前已经请求并载入,下次请求时候,就会启用基本切换,也就是直接使用之前的page过场,而不是再次发起Ajax请求。这就是Mobilebone请求页面的缓存机制。但是,实际开发时候,有些页面数据是需要实时更新,不能被缓存的。此时怎么破?很简单,使用 data-reload="true"即可( ="true"可缺省)!例如下面代码演示:

<a href="ajax.html" data-reload>

于是,请求的页面就不会被缓存了,而是不断的新旧替换。

对了,Mobilebone中的所有Ajax请求都加了时间戳,也就是只要有请求发生,基本上都不会使用浏览器缓存。

4. Ajax加载的loading效果
Ajax是个需要等待响应的过程,尤其网络较差的情况,比如高峰时段的地铁。Mobilebone自带loading效果。

默认情况的loading效果为, 35%白色半透明全屏遮罩,中间是个斑斓的菊花旋动效果,如下截图:
默认的loading效果

此效果对于90%的移动开发,以及部分的PC页面是适用的。但是,应用场景千千万,有时候,我们 loading可以希望出现在局部,例如,我们点击的按钮、或导航上。此时该怎么办?对此,Mobilebone也留了一手。很简单,使用 data-mask="true"( ="true"可缺省)就可以了。如下所示:

<a href="ajax.html" data-mask>

于是,当我们点击这个链接时候, loading相关的HTML就会显示在这个 a元素中,通过简单的CSS控制,就能实现我们需要的自定义loading效果了,例如,只覆盖按钮,或者菊花在文字后面显示。如下面两截图效果:

按钮覆盖loading

loading跟随按钮文字效果

若有兴趣,可以 轻戳这里访问体验下。

对了,插一句:Mobilebone已经对Ajax连续点击可能会重复请求的问题作了处理,大家无需担心额外的请求损耗。

5. 避免Ajax加载,使用传统刷新
Mobilebone默认会对同域的地址做Ajax请求无刷新加载。但是,万一人家就是希望要请求呢?以及,虽然跨域,但是人家依然希望使用Ajax请求了(如跨子域而已)。

轮到 data-ajax属性出场了。如下代码:

<a href="ajax.html" data-ajax="false">  // 此情况下也可使用data-rel="external"

于是,点击上面 <a>元素时候,就会是浏览器的刷新跳转。

如果人家要页面上所有的链接,或者大部分都是跳转,总不能一个一个设置 data-ajax="false"吧,哈,Mobilebone提供了一个全局参数, Mobilebone.captureLink,只要设置成 false布尔值,页面所有链接诶都是传统可刷新跳转链接。

Mobilebone.captureLink = false;

例如, 测试引导首页就是这么设置的。

事情还没有结束。Mobilebone自带域名判断技能,如果跨域,默认会认为是刷新链接。但是,XMLHttpRequest 2.0支持Ajax跨域。例如 a.qq.com下的页面请求 b.qq.com, 此时需要按照Ajax请求来走,怎么办?还是 data-ajax, 这回值设置成 "true"就可以了。

<a href="//b.qq.com/ajax.html" data-ajax="true">

六、mobilebone.js与过场回调方法

所谓“过场回调”,就是从牛A页面切换到牛C页面时候,触发的一些回调函数。

Mobilebone提供了多个回调接口,以应对各种交互需求。有如下四个:

  • onpagefirstinto(pageInto, pageOut, response)
    当过场页面第一次进入的时候执行,一般用在事件绑定,或实现元素动态显示。支持三个参数: pageInto 进入的page元素。这个参数一定会存在的。 pageOut 离开的page元素。这个参数可能为 null, 如页面刷新时候。 response 返回的数据。这个参数多半应用在Ajax请求时候。
  • callback(pageInto, pageOut, response)
    每次过场页面进入的时候都会执行。参数与 onpagefirstinto含义一致,不赘述。
  • animationstart(page, into_or_out)
    过场动画开始的时候执行。离开的页面和进入的页面都会触发。两个参数: page 当前动画的page元素。 into_or_out 字符串。只可能下面两个值之一: "into", "out"
  • animationend(page, into_or_out)
    过场动画结束的时候执行。离开的页面和进入的页面都会触发。参数与 animationstart含义一致,不赘述。

下面问题来了,如何绑定这些回调方法?

OK,跟Ajax参数绑定类似,使用自定义属性。同样是两种模式: data-*data-params.

例如下面这个 data-*模式:

<div id="pageHome" class="page out" data-onpagefirstinto="home" data-animationstart="start">

或者下面这个 data-params模式:

<div id="page1" class="page out" data-params="animationstart=start&animationend=end">

模式不是重点,重点是函数名关键字。例如 data-onpagefirstinto="home"表示什么意思呢?

有些类似Ajax的回调,但有差别。在默认没有任何设置的情况下,Mobilebone会认为 home是个全局函数的名字。于是,会使用类似 window.home()的形式执行该回调方法。但是,显然,JS中应该是要尽量避免不必要的全局变量的,对于实际项目而言,都是全局方法是不实际的。于是,Mobilebone暴露了一个可以修改回调主对象的接口, Mobilebone.rootTransition. 例如,你的页面有如下对象:

FUN = {
    home: function(pageInto, pageOut, response) {},
    start: function(page, into_or_out) {},
    end: function(page, into_or_out) {}
};

则,你就可以设置:

Mobilebone.rootTransition = FUN;

“哎呀,我不想修改全局,只想局部开花”,OK,没问题,使用 root关键字修改根对象。例如:

<div id="page1" class="page out" data-root="window">

哈, page1的回调函数又变成 window对象下面的啦~ 同样,支持 data-params查询字符串模式。另外, data-root也支持对象级联,可以帮你获取层级较深的方法。

关于过场回调,如有兴趣,可 轻戳这里浏览观摩体验。

直接全局设置
有些回调,每个页面发生过场的时候都会执行,我总不会每个页面都加一个 data-callback吧,又累又啰嗦。此时,你可以使用全局回调设置。直接:

Mobilebone.callback = function() {};

每次有页面进入都会执行,此实例可参考 头尾固定的那个例子

如果发生冲突,也就是 data-callback也存在,则直接覆盖全局的 Mobilebone.callback方法。

七、mobilebone.js与使用其他过场动画

mobilebone.css默认只提供了一种过场效果,就是左右 slide效果。

如果你希望有更多的过渡效果。试试外链一个 animate.css, 此CSS位置位于Github项目的 test/transition/animate.css, 包含 fade, slideup, slidedown, turn, flow等多个过场动画效果,然后,添加特定属性,就可以实现我们的效果了,很easy!

<link rel="stylesheet" href="http://rawgit.com/zhangxinxu/mobilebone/master/src/mobilebone.css">

于是,我们在page元素上,使用 data-form="xxx"data-params="form=xxx"指定特定的过场动效。例如, fade淡入淡出效果:

<div id="page1" class="page out" data-form="fade">

八、mobilebone.js与模块化加载

mobilebone.js可以符合AMD, CMD规范的加载器加载。例如 seajs, 或 requirejs.

用法其实很简单的:

var Mobilebone = require('mobilebone');

然后,用法基本上就跟平常时候一样,除了需要手动初始化一下:

// Mobilebone API设置...然后...
Mobilebone.init();

若有兴趣,可参考 test/modular-load中各个文件的源代码示意( index.html使用的是 seajs, require.html使用的是 require.js)。这里要看代码,效果没啥看头。

九、mobilebone.js与地址栏前进、后退与刷新

Mobilebone强大的另外一个体现就是利用HTML5 history API和地址栏融为了一体。

地址栏的前进、后退或者刷新都跟传统网页一样,可以准确显示对应内容。因此,无论是Web APP或者Hybird APP,手机上的返回键都能很好地操控我们的内容呈现,就跟Native APP感受一样(文章开始的视频应该有所体现)。

原理
早些年时候,我直接使用 hash做路由指向,后来发现经常会干扰定位。原因可参考我之前的文章:“ URL锚点HTML定位技术机制、应用与问题”。

这里有必要再次感谢下jQuery Mobile. Mobilebone的history处理与jQuery Mobile一样,路由地址前面加了一个 &符号,从而解决了锚点定位的问题。

当然,从使用者的角度讲,这些你都不需要关心。

十、mobilebone.js与插件扩展

mobilebone.js核心就是切换,其也只做了这一件事情。正是因为这种简单与专一,方能体现其强大。如果你想有更丰富强大的功能,你可以很自如地进行扩展。

前面的 animate.css过场动效就是不错的扩展。当然,不知CSS,JS层面的扩展更具有潜力。

举个例子,你希望swipe时候,页面也有过渡效果,OK,你参考API文档扩展下就可以了,或者添加键盘控制,实现类似在线幻灯片浏览的效果,也是可以的。

plugins/ppt文件夹下面,就有我写的一个在线幻灯片演示插件,做的事情其实很简单,单击非链接区域,上下左右键盘,以及鼠标滚动,会让幻灯片前后播放。

您可以在PC或者pad上 访问该演示页面

当然,如果你有其他idea, 也能做出其他很精彩的作品。

十一、mobilebone.js其他tips说明

1. tap/click事件依赖
该Tips还是蛮重要的!所谓事件依赖,就是,如果浏览器大环境支持 tap事件(比如使用了含touch events的Zepto.js),则使用 tap事件来触发一系列的过场行为,否则就使用 click事件。然而,大家可能都知道的,在移动设备上, click具有较长时间的延迟,用户在操作的时候总会有点怪怪的不顺畅的感觉。怎么办?在这里,我必须郑重推荐下 fastclick.js. 很多小伙伴都在用它,Github上面的star要奔万的节奏去了, https://github.com/ftlabs/fastclick.

直接引入 fastclick.js,然后如下代码绑定:

FastClick.attach(document.body);

然后我们就能愉快地在移动设备上玩耍啦!此js对Mobilebone很友好,有种千年好基友的感觉。在 test/complex演示的模拟微信交互页面上就使用了 fastclick.js.

2. 一些原型扩展方法

  1. 给元素扩展了一个 getParentElementByTag方法,根据标签寻找匹配的父元素,没有返回 null.
  2. 给字符串扩展了个 queryToObject方法,可以把查询字符串转换成对象。

3. 已知问题

  1. 一些老三星手机上,会出现第一次animation页面比例突然变小再恢复的诡异问题。希望有经验的朋友赐教!

4. 其他杂七杂八tips

  1. 在Github上查看 mobilebone.js时候,最好在后面加上 ?ts=4会以最佳排版效果显示。
    https://github.com/zhangxinxu/mobilebone/blob/master/src/mobilebone.js?ts=4
  2. Github上 mobilebone.js以及 mobilebone.css都是非压缩版本(因为我比较懒),实际上线,需要大家自行压缩。我测试了下,现在写这段文字的此时此刻最新的JS版本压缩后只有 8.69K, Gzip后真的只有3~4K,跟着图标大小差不多。

十二、mobilebone.js API文档

见下面表格,颜色淡的就是表示不常用的,正常颜色的是可以关注的:

API名称 类型 默认值 示例 吐槽
Mobilebone.support 布尔值 - - 是否兼容Mobilebone, 只读,亲,只读
Mobilebone.VERSION 字符串 - - 当前mobilebone.js的版本号,只读,注意了,只读
Mobilebone.autoInit 布尔值 true Mobilebone.autoInit = true 是否DOM加载完毕后自动初始化,默认为true. 如果页面加载完毕之后的require加载,此值失效,按false处理。
Mobilebone.captureLink 布尔值 true Mobilebone.captureLink = true 是否捕获页面上的a标签,执行无刷新过场效果。此为全局设置,影响整个页面。默认为true
Mobilebone.rootTransition 对象 window Mobilebone.rootTransition = window 过场回调方法的根对象。默认是全局window.
Mobilebone.classPage 字符串 "page" Mobilebone.classPage = "page" page元素的标志类名
Mobilebone.classMask 字符串 "mask" Mobilebone.classMask = "mask" mask元素的标志类名
Mobilebone.pushStateEnabled 布尔值 true Mobilebone.pushStateEnabled = true; 是否启用历史记录。此参数我是没有想到需要使用的理由,但总感觉可能用到,于是就放着。
API名称 类型 返回类型 参数 示例 吐槽
Mobilebone.transition(pageInto, pageOut, back, options)

或者

Mobilebone.transition(pageInto, pageOut, options)

函数 - pageInto DOM元素。表示进入的page元素. 必须参数。

pageOut DOM元素。表示要移出的page元素. 可选。没有移出元素使用 null.

back 布尔值。是否反方向过场。可缺省。

options 对象。此参数多内部使用。一般有用的是两个参数接口: idresponse.

Mobilebone.transition(element);
Mobilebone.transition(element1, element2);
Mobilebone.transition(element1, element2, true);
Mobilebone.transition(element1, element2, { id: “only” });
Mobilebone.transition(element1, element2, true, { id: “only” });
此API在插件扩展的时候应该是最常用的。此方法为Mobilebone切换的核心。含缓存机制、事件回调触发等。
Mobilebone.getCleanUrl(trigger, url, params) 函数 字符串 trigger DOM元素。一般表示 <a>元素。可选参数,和 url至少一个存在。

url 字符串。Ajax请求地址。如果 trigger有合法 href值,此参数酱油。可选参数,和 trigger至少有一个有效。

params 对象或者字符串。主要用来获得请求查询数据.可选。

Mobilebone.getCleanUrl(elementOfA);
Mobilebone.getCleanUrl(elementOfA, ”, “a=1&b=2″);
Mobilebone.getCleanUrl(null, “xxx.html”);
Mobilebone.getCleanUrl(null, “xxx.html?a=1&b=2″);
Mobilebone.getCleanUrl(null, “xxx.html”, “a=1&b=2″);
获得干净完整的Ajax请求地址。基本上,此函数API内部用得多,大家大可不必关心。
Mobilebone.getPage(children) 函数 DOM元素
或null
children DOM元素。必须参数。 Mobilebone.getCleanUrl(childElement) 根据子元素获取当前所在的page元素。
Mobilebone.createPage(dom_or_html, element_or_options, options) 函数 - dom_or_html DOM元素或字符串。必须参数。

element_or_options DOM元素或者对象。可选参数,作用是获知需要移除的页面。可以是 <a>元素, page元素,也可以是第3个 options参数。

options 键值序列对象。可选参数。此参数多内部触发,基本上来自Ajax请求的参数。主要作用是获得 response返回数据。

Mobilebone.createPage(pageDom);
Mobilebone.createPage(generalDom);
Mobilebone.createPage(‘<div class=”page out”>xxx</div>’);
Mobilebone.createPage(‘<p>xxx</p>’);
Mobilebone.createPage(pageDom, triggerLink);
Mobilebone.createPage(pageDom, { reponse: ‘<div…>’ });
Mobilebone.createPage(pageDom, triggerLink, { reponse: ‘<div…>’ });
重要API. 直接根据DOM或者HTML字符串创建页面,并载入。别看API名字较长,好像很复杂,其实很简单滴。
Mobilebone.getFunction(keys) 函数 对象

函数
keys 字符串。必须参数。当字符串级联的时候,例如’a.b.c’, 用来返回纯正的 window.a.b.c这个对象,才能执行与调用。 Mobilebone.getFunction(“a.b.c”) 此API内用,大家很少会用到,不要太关心。
Mobilebone.ajax(trigger_or_options) 函数 - trigger_or_options <a>元素或者Ajax请求参数对象。必须参数。 Mobilebone.ajax(document.querySelector(“a”));
Mobilebone.ajax({
  url: ‘xxx.html’,
  success: function() {}
});
很重要,应该会比较多用到的API,大家需要留意。
Mobilebone.isBack(page_in, page_out) 函数 布尔值 page_in 元素。必须参数。进入的元素。

page_out 元素。可选参数。离开的元素。

- 此API没什么机会使用的,内用居多,不必太在意。
Mobilebone.jsonHandle(json) 函数 DOM元素

HTML字符串
json JSON数据。必须参数。 - 此方法JSON请求必用。全局方法,因此,如果存在多个JSON需要处理的情况,请使用JSON数据中特定的标志量进行区分,例如,返回个 id. 如:
{
  "id": "homePage" ,
  "data": []  
}

和这个:

{
  "id": "listPage" ,
  "data": []  
}

Mobilebone.init(); 函数 - - - 初始化方法。默认DOM载入完毕会执行,无需关心。如果 Mobilebone.autoInitfalse, 或此方法在页面 load完毕后动态载入,则需要手动初始化。
Mobilebone.handleTapEvent(event) 函数 - - - 起初我只是为了排版好看才将此方法暴露出来的。后来发现,某些场景还是可以用到的。比方说你做了某些操作,直接把 click给永久消灭了,然后使用自己的自定义tap方法,此时就可以类似这样处理:
document.body.addEventListener('myCustomTapEvent', Mobilebone.handleTapEvent, false);

来绑定过场效果。

十三、mobilebone.js结语与展望

一分耕耘一分收获,终于赶在月底前把这篇文章发布了,扳一扳手指头,快40天去了,鲜有项目做这么长时间。来鹅厂目前最大的收获之一就是做产品的态度,一定要花足够的精力去精雕细琢,kill每一个痛点,完善每一个体验。虽然过程很辛苦,但是做出来的东西大家会都喜欢。看上去好像谁到知道,做产品要用心,但事非经过不知难,一定要亲历与感悟,才能真正成为自己所得之物。

虽然上面调侃多次“说不定回火”,但自己实际并没有真在意。我并不确定有多少人会使用mobilebone.js, 但是,唯一我确定的是,心有多大,舞台就有多大,如果没有制作精品的态度,没有完成世界top级作品的胸怀,没有用心的反复雕琢与实践,一定是不会火的,最多就是发布时候众人捧个场、鼓个掌,然后,就没有然后了,就像千千万万昙花一现的小企业一般。

所以,细心的你可能发现, mobilebone.js中的注释都是英文的,且API用法,参数,示例都放上面了;提示信息也是蹩脚英文,ReadMe.md也有英文介绍。当下,虽举目三尺皆白壁,但心在壁外三万里。用人话表示就是,虽然我身处一个小屋子,但我希望我做的东西能够漂洋过海得到肯定。因此,花了很多额外的功夫做了些国际化的工作,万一哪个老外慕名前来,也不会因为看不懂中文文档而放弃。

谋事在人成事在天,做好自己能够最好的一切,期待理想之花静静绽放。恩,至少,我自己用起来是很顺手的!

希望大家多多支持,共同建设,提出问题或提供建议!

回头,如果大家关注度不错,我会申请个相关域名,把此项目独立出去……一切才刚刚开始……

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址: http://www.zhangxinxu.com/wordpress/?p=4381

(本篇完)

有话要说?点击 这里发表评论。

相关 [mobilebone js mobile] 推荐:

Weaver Mobile招聘

- HACK21 - 弯曲评论
Weaver Mobile是一家专注于下一代SNS的移动互联网公司. 成立于2011年4月,并获得了业界著名的风险基金的投资和支持. 我们将会在六月开始在北京上地建立研发中心. 诚恳的邀请在Android,iPhone应用系统开发有兴趣,or/and 有经验的朋友加盟. 我们期望您,具备良好的数据结构的基础,具备良好的和至少C语言功底.

Mobile App 将死?!

- - Tech2IPO
日前,Mozilla 产品副总监 Jay Sullivan 称移动应用不久即将成为历史,未来将是移动 Web 应用的天下. 光盘好歹还能当杯垫,可怜 Mobile App,难道就这样一下跌落进历史的垃圾堆. Mozilla 的产品副总监杰 • 沙利文 (Jay Sullivan, 上图) 日前表示,移动终端应用(Mobile App)没有未来,真正有前途的是移动 Web 应用(Mobile Web App).

jQuery Mobile 1.3.0发布

- - InfoQ cn
jQuery基金会发布了旗下的JavaScript和HTML5/CSS框架 jQuery Mobile 1.3.0. 更新主要集中在响应式的web设计并新增了多个移动应用的widget. 响应式web设计(RWD)旨在提供最佳的用户浏览体验,不管使用的是什么设备、什么浏览器. RWD使用CSS媒体查询(media queries)语言在浏览器中动态适配页面布局,而不是在服务端检测用户代理(User Agent).

WebView JS 交互

- - ITeye博客
WebView加jquery做页面会怎么样呢. // 创建WebView对象. // 把programList添加到js的全局对象window中,. // 这样就可以使用window.programList来获取数据. * 定义js回调java函数. // 绑定键盘的向上,向下按钮事件触发相应的js事件.

关注:jQuery Mobile来了!

- sheng - 膘叔
  为了让移动设备也能用上jQuery,jQuery开发团队发布了jQuery移动设备版开发项目jQuery Mobile Project(http://jquerymobile.com). jQuery Mobile不仅会给主流移动平台带来jQuery核心库,而且会发布一个完整统一的jQuery移动UI框架.

Mobile Web调试工具Weinre

- - 移动开发 - ITeye博客
现在、将来,用移动设备上网越来越成为主流. 但对于开发者们来说,移动web的调试一直是个难题,前期可以使用模拟器来协助调试,但到了真机调试阶段就让人非常头痛. 而Weinre就是解决这难题的利器.   Weinre的本意是Web Inspector Remote,它是一种远程调试工具. 功能与Firebug、Webkit inspector类似,可以帮助我们即时更改页面元素、样式,调试JS等,下面就简单介绍下如何使用.

JS游戏引擎

- 米随随 - HTML5研究小组
If you don’t have anything better to do and want to help fellow redditors interested in JS game dev out, feel free to fork the list and modify it as you like.

來源請求.js

- 红烧鲤鱼 - Blog: timdream
很早以前就想講了,但講了大概又會被戰. 相較於英文維基百科,中文維基百科在社會和歷史條目充滿了 systemic bias. 但是那些主觀論述又不是編輯者有意加進去的,而是某種編輯者存在的社會所給予的暗示(Inception?)與集體共識,而不是原本百科全書應該有的可驗證的事實. 因為是暗示又是共識,所以有自覺的百科編輯者反而是少數;中文維基只好長成現在這個樣子了.

Js删除节点

- - JavaScript - Web前端 - ITeye博客
 方式一:传this参数调用方法:.  方式二:js方法中通过选择器获取节点:. //此处删除的是a节点 }. 方式三:通过jQuery方式获取节点:(尚未测试,有待测试. 此处a标签传this到js中,js通过this(即a节点)取parent(即p节点). (1)p.remove();可直接删除整个p节点.

Vision Mobile:2001-2010 手机市场 Top 5

- Shanshan - 爱范儿 · Beats of Bits
自从 iPhone 和 Android 问世以来,手机市场便进入了一轮新的变革. 过去一些看似无法撼动的手机行业王者,在新的市场竞争中不断丧失领地,一些曾经 PC 行业的公司则以更加迅捷的反应加入到这场移动互联网的巨变之中. Vision Mobile 盘点了过去 10 年间位居前五位的手机制造厂商,让我们得以更加直观的了解这场变革.