这篇文章发布于 2014年10月31日,星期五,13:34,归类于 JS实例, Mobile相关。 阅读 295266 次, 今日 12 次 291 条评论
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两个分支的测试页):
如果你是在手机浏览器访问本页面,试试直接点击这里感受一番。
二、mobilebone.js项目、资源以及八卦
Mobilebone项目已经发布到Github上了,项目地址为:https://github.com/zhangxinxu/mobilebone
注意注意:有任何使用问题,建议前去 https://github.com/zhangxinxu/mobilebone/issues 提问,方便有其他类似问题的小伙伴发现与查找,我也能及时反馈与更新。
如果你觉得此项目很赞,欢迎star, 如果你想参与建设,欢迎fork!
clone该项目可使用下面命令行代码:
git clone git://github.com/zhangxinxu/mobilebone.git
也可以使用npm
:
npm install mobilebone
目录结构:
-- --example 精湛示例 --docs APIs文档 --test UI比较挫的测试页面 index.html 测试引导 --base-slide 基本切换 --ajax-html Ajax请求HTML测试 --ajax-json Ajax请求JSON数据测试 --callback 回调测试 --transition 其他切换效果测试,animate.css可以关注下 --fixed-header-footer 固定的头部与底部 --form-submit 表单提交 --prevent-default Mobilebone默认行为的中断与介入 --modular-load 模块化加载测试 --backbone 与backbone组合使用演示 --complex 复杂实例,微信模拟。fastclick.js好基友可以关注下 --src mobilebone.js和mobilebone.css文件
初次将项目publish到npm上,经验不足,若有什么不对头的地方,欢迎诸位帮忙指正!
更新于2014-11-13 01:31
新的专门的API文档页面已经出炉,可以点击这里或者这里查看。
更深入内容,还是需要参考本文内容。
更新于2014-11-14 16:45
今天博友_iancj
发布了基于mobilebone.js的webapp demo一枚,地址是http://iancj.github.io/qq/, 项目地址是:https://github.com/iancj/qq. 其对Mobilebone的评价如下截图(Mobilebone.js真的很好用):
欢迎其他小伙伴展示你的实例,加入Mobilebone的建设。
为什么叫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 appHybrid 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代码:
传统网页,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(); // 初始化
记住,一个页面只能初始化一次,以免文档事件重复绑定。
页面title变化
当从一个页面切换到另外一个页面时候,自然是会有title
的变化的。如果是基本切换,则取自进入page页面元素的data-title
属性值;如果是Ajax请求,且返回的是HTML字符串,如果返回标签包含title
元素,则会取title
的值作为页面的标题,或者通过触发行为的a
元素的data-title
属性设置。
具体可参考Ajax请求HTML测试页面的相关源代码。
四、mobilebone.js与基本切换
所谓基本切换,指的是无请求,无延迟的即时切换。表现为:每个page在第1次加载完毕后,就已经存在页面,所谓的切换仅仅是这些page元素的位置变化。
就好比我们使用PowerPoint文件,每次打开一个屁屁踢幻灯片文件,一个一个幻灯片页面实际都是已经存在的,我们的浏览,其实都是幻灯片页面的位置变化,这就是基本切换。
在DOM层面,只有一种情况会触发基本切换,href
值为锚链的a
元素。例如:
<a href="#pageId">
于是,当我们tap/click
这个a
元素的时候,Mobilebone会自动寻找id
为pageId
的页面,如果此页面存在,则发生切换动画;如果没有该页面元素,没有任何反应,死链。
若有兴趣,可以轻戳这里访问感受基本切换效果。
相反的过场方向
动画的方向不可能都是从右往左的,例如,返回,显然是需要刚进入动画相反,符合正常认知。要实现,很简单,通过添加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秒。
不过仍有两个注意点:
- 如果
href
值正常,则data-url
地址会被忽略,依然使用href
对应地址作为Ajax请求地址。 - 没有
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片段代码”。
返回页面的title
如果是返回完整网页标签结果,则会使用<title>
标签里面的文字作为请求页面的title
;如果是返回HTML片段,抱歉,你只能在点击的元素上通过data-title
属性设置。
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加载建议
//zxx: 很多人这里有误解:并不是推荐大家直接载入HTML页面,而是可以尝试不依赖Mobilebone你自己的方法装载数据。
虽然Mobilebone提供了直接请求JSON数据的方法,并提供了视图渲染接口。但是,以我个人经验,对于实际开发,这种实现策略是不推荐的。我认为更好的实现方法应该是这样的。页面骨架,也就是page主体,也就是一个空div
默认就载入,然后所有的切换都是基本切换,而不是Ajax切换。在切换即将开始的时候(回调),您就可以使用自己,例如Zepto的Ajax方法去请求你需要的JSON数据,做你任何想做的事情,完全没有Mobilebone的限制。
页面slide是有时间的,350ms, 这个时间点很可就就完成呈现了最终的页面。于是,我们看到的就是,一点击,页面slide, slide结束,内容呈现。哇哦哦~~操作感不要太流畅哦!而且技术上更可控,因为数据请求、处理与Mobilebone完全解耦。
当然,如果就是个原型页面、简单的静态页面,或者是不喜JS的小伙伴,依赖Mobilebone的Ajax整体请求与呈现策略显然是最好的选择,因为,你什么都不需要做~
补充于2017-07-06
上面提到的“更好的JSON和HTML加载建议”现在google提出了一个专门的名词,叫做“App Shell 模型”,其思路都是一致的,如果无法访问可以查看这里的备份地址。
其核心思想都是:核心应用基础架构和 UI 从数据中分离出来。请务必使初始加载尽可能简单,在打开网络应用后仅显示页面的布局。
3. 请求页面的缓存机制
默认情况下,Ajax请求的页面,如果之前已经请求并载入,下次请求时候,就会启用基本切换,也就是直接使用之前的page过场,而不是再次发起Ajax请求。这就是Mobilebone请求页面的缓存机制。但是,实际开发时候,有些页面数据是需要实时更新,不能被缓存的。此时怎么破?很简单,使用data-reload="true"
即可(="true"
可缺省)!例如下面代码演示:
<a href="ajax.html" data-reload>
于是,请求的页面就不会被缓存了,而是不断的新旧替换。
对了,Mobilebone中的所有Ajax请求都加了时间戳,也就是只要有请求发生,基本上都不会使用浏览器缓存。
v2.3.2+ 新增
data-reload="root"
, 表示相对“url根地址重新加载”。于是data-reload
就有了两种不同的使用场景:
- url完整地址重加载:
data-reload
/data-reload="true"
. - url根地址重新加载:
data-reload="root"
(v2.3.2+)
分别表示什么意思呢?
url完整地址重加载
如下两个请求:
<a href="detail.php?id=112" data-reload="true">请求详情页</a>
<a href="detail.php?id=113" data-reload="true">请求详情页</a>
可以看到查询id
是不一样的。所谓“完整地址重加载”是指,只有在第二次请求的页面url
(包括查询字符串)完全匹配的时候,才移除缓存,重新加载!
比方说上面的两个请求,最后页面HTML会有两个独立的页面。
url根地址重加载
请求地址还是一样,但data-reload
值为root
:
<a href="detail.php?id=112" data-reload="root">请求详情页</a>
<a href="detail.php?id=113" data-reload="root">请求详情页</a>
这里的就是“根地址重加载”,指只要Ajax请求的url的根地址是一样的,就不会缓存,直接清除之前同源页面。
所以,这里,页面上永远最多就一个详情页对应HTML. 很多小伙伴喜欢使用全局id
绑定事件,此时,就务必需要设置data-reload="root"
, 以免id
冲突,事件重复绑定等问题。
更新于2014-04-13
v2.4.4+ 移除了data-reload="root"
,使用了更智能的缓存更新机制,所以上面2014-01-26的更新作废,向前兼容,无需修改。
4. Ajax加载的loading效果
Ajax是个需要等待响应的过程,尤其网络较差的情况,比如高峰时段的地铁。Mobilebone自带loading效果。
默认情况的loading效果为,35%
白色半透明全屏遮罩,中间是个斑斓的菊花旋动效果,如下截图:
此效果对于90%的移动开发,以及部分的PC页面是适用的。但是,应用场景千千万,有时候,我们loading
可以希望出现在局部,例如,我们点击的按钮、或导航上。此时该怎么办?对此,Mobilebone也留了一手。很简单,使用data-mask="true"
(="true"
可缺省)就可以了。如下所示:
<a href="ajax.html" data-mask>
于是,当我们点击这个链接时候,loading
相关的HTML就会显示在这个a
元素中,通过简单的CSS控制,就能实现我们需要的自定义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→ options)
当过场页面第一次进入的时候执行,一般用在事件绑定,或实现元素动态显示。支持三个参数:- pageInto
- 进入的page元素。这个参数一定会存在的。
- pageOut
- 离开的page元素。这个参数可能为
null
, 如页面刷新时候。
response返回的数据。这个参数多半应用在Ajax请求时候。
- options(v2.1.0+)
- 之前的参数
response
重置为options
,options
为{}
对象,根据应用场景不同,options
属性也有所不同。通常常用的参数有:- options.response 返回的数据。这个参数多半应用在Ajax请求时候。
- options.target (触发过场)点击的页面元素。
- options.id 页面标示
id
, 一般仅在url
请求时候存在。 - options.history 是否在浏览历史中添加一条记录。此属性大可不必关心。
- options.remove 是否删除同
id
的页面。此属性大可不必关心。
- callback(pageInto, pageOut,
response→ options)
每次过场页面进入的时候都会执行。参数与onpagefirstinto
含义一致,不赘述。 - fallback(pageInto, pageOut,
response→ options)
每次过场页面退出的时候都会执行,v.1.1.4+
新增。参数与onpagefirstinto
含义一致,不赘述。 - animationstart(page, into_or_out, options)
过场动画开始的时候执行。离开的页面和进入的页面都会触发。两三个参数:- page
- 当前动画的page元素。
- into_or_out
- 字符串。只可能下面两个值之一:
"into"
,"out"
。
- options
- v2.1.0新增,包含一些参数,方便回调处理。含义与
onpagefirstinto
一致,不赘述。
- animationend(page, into_or_out, options)
过场动画结束的时候执行。离开的页面和进入的页面都会触发。参数与animationstart
含义一致,不赘述。
重要:补充于2015-05-30(v2.5.8)
尤其当使用data-callback
和data-fallback
处理一些回调的时候,有可能前后两个页面结构一致,数据不一样,就很有可能出现id
一致的情况,如果单纯使用$("#ID")
或document.querySelector("#ID")
, 则得到的元素并不是新页面你希望选择的元素。怎么办,请使用回调方法中的页面参数作为容器去获取对应的元素,例如:
Mobilebone.callback = function(pagein) {// NOT: var element = document.querySelector("#ID");var element = pagein.querySelector("#ID"); // do sth by using elememt... };
下面问题来了,如何绑定这些回调方法?
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 APPHybrid 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. 一些原型扩展方法
- 给元素扩展了一个
getParentElementByTag
方法,根据标签寻找匹配的父元素,没有返回null
. 给字符串扩展了个此方法在queryToObject
方法,可以把查询字符串转换成对象。v1.1.3+
中私有
3. 已知问题
- 一些老三星手机上,会出现第一次animation页面比例突然变小再恢复的诡异问题。希望有经验的朋友赐教!
4. 其他杂七杂八tips
- 在Github上查看
mobilebone.js
时候,最好在后面加上?ts=4
会以最佳排版效果显示。https://github.com/zhangxinxu/mobilebone/blob/master/src/mobilebone.js?ts=4
- Github上
mobilebone.js
以及mobilebone.css
都是非压缩版本(因为我比较懒),实际上线,需要大家自行压缩。我测试了下,现在写这段文字的此时此刻最新的JS版本压缩后只有8.69K
, Gzip后真的只有3~4K,跟着图标大小差不多。
十二、mobilebone.js API文档
见下面表格,颜色淡的就是表示不常用的,正常颜色的是可以关注的:
API名称 | 类型 | 默认值 | 示例 | 吐槽 |
---|---|---|---|---|
Mobilebone.support | 布尔值 | – | – | 是否兼容Mobilebone, 只读,亲,只读 |
Mobilebone.VERSION | 字符串 | – | – | 当前mobilebone.js的版本号,只读,注意了,只读 |
布尔值 | true | Mobilebone.autoInit = true | 是否DOM加载完毕后自动初始化,默认为true. 如果页面加载完毕之后的require加载,此值失效,按false处理。 | |
Mobilebone.captureLink | 布尔值 | true | Mobilebone.captureLink = true | 是否捕获页面上的a标签,执行无刷新过场效果。此为全局设置,影响整个页面。默认为true |
Mobilebone.captureForm(v2.0.0+) | 布尔值 | true | Mobilebone.captureForm = true | 是否捕获页面上的form表单元素的默认submit提交事件,执行无刷新提交以及过场效果。此为全局设置,影响整个页面。默认为true |
Mobilebone.rootTransition | 对象 | window | Mobilebone.rootTransition = window | 过场回调方法的根对象。默认是全局window. |
Mobilebone.mergeCallback(v1.1.4+) | 布尔值 | true | Mobilebone.mergeCallback= true | 全局的回调方法和每个页面上自定义的回调方法是合并还是覆盖。默认true表示合并。 |
Mobilebone.classAnimation(v2.1.1+) | 字符串 | "slide" | Mobilebone.classAnimation = "flip" | 过场动画相关联的类名 |
Mobilebone.classPage | 字符串 | "page" | Mobilebone.classPage = "page" | page元素的标志类名 |
Mobilebone.classMask | 字符串 | "mask" | Mobilebone.classMask = "mask" | mask元素的标志类名 |
Mobilebone.pushStateEnabled | 布尔值 | true | Mobilebone.pushStateEnabled = true; | 是否启用历史记录。此参数我是没有想到需要使用的理由,但总感觉可能用到,于是就放着。 |
Mobilebone.evalScript(v2.5.0+) | 布尔值 | false | Mobilebone.evalScript = true; | 是否执行Ajax请求的HTML字符串里面的内联JS脚本,默认不执行。 |
API名称 | 类型 | 返回类型 | 参数 | 示例 | 吐槽 |
---|---|---|---|---|---|
Mobilebone.transition(pageInto, pageOut, back, options)
或者 Mobilebone.transition(pageInto, pageOut, options) |
函数 | – | pageInto
pageOut null .back options id 和response . |
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
<a> 元素。可选参数,和url 至少一个存在。url 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内部用得多,大家大可不必关心。 |
函数 | DOM元素 或null |
children
|
Mobilebone.getCleanUrl(childElement) | 根据子元素获取当前所在的page元素。 | |
Mobilebone.createPage(dom_or_html, element_or_options, options) | 函数 | – | dom_or_html
element_or_options data-title 等。可以是<a> 元素,page 元素,也可以是第3个options 参数。options 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
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.submit(formElement) (v2.0.0+) | 函数 | – | formElement
<form> 表单元素。必须参数。 |
Mobilebone.ajax(document.querySelector(“form”)); | 可以让页面的表单的默认提交事件变成Mobilebone下的Ajax提交事件,会把返回内容变成新页面并执行过场。 |
Mobilebone.isBack(page_in, page_out) | 函数 | 布尔值 | page_in
page_out |
– | 此API没什么机会使用的,内用居多,不必太在意。 |
Mobilebone.jsonHandle(json) | 函数 | DOM元素 或 HTML字符串 |
json
|
– | 此方法JSON请求必用。全局方法,因此,如果存在多个JSON需要处理的情况,请使用JSON数据中特定的标志量进行区分,例如,返回个id . 如:
{ "id": "homePage" , "data": [] } 和这个: { "id": "listPage" , "data": [] } |
Mobilebone.init(); | 函数 | – | – | – | 初始化方法。默认DOM载入完毕会执行,无需关心。如果Mobilebone.autoInit 为false , 或此方法在页面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也有英文介绍。当下,虽举目三尺皆白壁,但心在壁外三万里。用人话表示就是,虽然我身处一个小屋子,但我希望我做的东西能够漂洋过海得到肯定。因此,花了很多额外的功夫做了些国际化的工作,万一哪个老外慕名前来,也不会因为看不懂中文文档而放弃。
谋事在人成事在天,做好自己能够最好的一切,期待理想之花静静绽放。恩,至少,我自己用起来是很顺手的!
希望大家多多支持,共同建设,提出问题或提供建议!
回头,如果大家关注度不错,我会申请个相关域名,把此项目独立出去……一切才刚刚开始……
十四、重要更新说明
1. 更新于2014-12-30
首先从v2.0.0
开始对表单提交过场进行了支持。然后,注意然后,有一个重大的介入,就是即将发布的v2.2.0
版本加入了Mobilebone中介阻断介入机制,也就是可以让你在Mobilebone执行内置的行为之前可以让你做很多其他的事情,你可以决定是继续还是阻断,执行其他行为。
这就是data-preventDefault, 我一般写做data-preventdefault(属性名不区分大小写)。
其阻止(或介入)Mobilebone的默认行为包括,页面过场;a
链接交互;表单提交。
链接交互
例如,页面上有如下HTML:
<a href="form.html">点击加载一个表单</a>
如果没有其他设置,Mobilebone会自动请求form.html
这个页面并过场载入。但是,往往,我们可能需要先判断用户是否已经登录了,此时,就需要data-preventdefault
(不区分大小写)的介入。如:
<a href="form.html" data-preventdefault="isLoginout">点击加载一个表单</a>
于是,我们就可以在isLogin
这个方法中做阻断判断了:
var isLoginout = function(target) {
// 支持一个参数target, 指的就是对应的a元素
// 如果没有登录,返回true
if (isLogin == false) return true;
};
从上面代码可以看到,当data-preventdefault
中介函数返回值为true
的时候,就会中断Mobilebone的默认行为,你就可以做一些你想做的其他事情,例如,先弹出个登录弹框。
表单提交前的验证
data-preventdefault
中介函数还有一个很重要的应用就是表单验证。默认情况下,表单点击提交按钮,就会走原生验证,然后Ajax过场。但是,实际开发,验证是交给自己,而不是浏览器,于是,在提交之前,我们有必要验证下,此时,就得靠data-preventdefault
.
写在form
标签上,如下:
<form method="get" action="search.html" data-preventDefault="validate_false" novalidate></form>
由于data-preventdefault
中介函数返回true
时候才中断,因此,对应的函数关键字应该是“验证不通过”的意思,例如这里的validate_false
.
var validate_false = function(form) { // 支持一个参数form, 指的就是表单元素 // 如果文本框没有值 if (input.value.trim() == "") { // 显示错误提示 // xxxx.show(); // 中断Mobilebone行为 return true; } };
页面过场(进入/离开)
page
页面元素上也可以使用此中介阻断API,其绑定以及函数参数与callback
/fallback
完全一致。
例如,我们Ajax请求页面的是一个弹框页面,此时,当前页面是不能离开舞台的,就可以使用data-preventdefault
中断。这个以后有机会再放置实例。
或者实现页面跳转效果等。
2. 更新于2015-01-11
新增2个自定义属性:data-container
和data-classpage
.
都是作用在链接a
元素上的,其中data-container
值指的是容器元素的id
, data-classpage
为类名。
① 当只有data-container
这个属性时候,Ajax请求装载的页面会append
到此属性值对应的容器元素中;
② 当data-container
和data-classpage
同时存在且合法的时候,可以实现内部过场(局部过场)效果。也就是,不是整个大的page滑来滑去,而是page里面小页面间的滑来滑去。存在这样的需求,载入一个页面,这个页面有固定头尾,然后也页面里面的content要滑来滑去。虽然之前的API也能实现类似效果,但是需要写回调之类控制,有些折腾,而有了data-container
和data-classpage
,事情就简单多了,指定容器,指定切换页面的关键类名,一切都结束了!具体可参见API文档中data-classPage的示意。
data-container
和data-classpage
触发的过场效果是不会有history
变化的,其他规则跟主page
切换一致,包括各种回调接口的使用等等。
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=4381
(本篇完)
- CSS touch-action简介与treated as passive错误解决 (0.448)
- web移动端浮层滚动阻止window窗体滚动JS/CSS处理 (0.373)
- 翻译-Mobile手机web开发问题们以及如何避免 (0.224)
- 小tips: 页面链接跳转历史URL不记录的兼容处理 (0.224)
- ajax与HTML5 history pushState/replaceState实例 (0.179)
- JS获取上一访问页面URL地址document.referrer实践 (0.179)
- 深度好文: 从js visibilitychange Safari下无效说开去 (0.179)
- 如何实现页面刷新后不定位到之前的滚动位置? (0.179)
- PhoneGap/Cordova控制iOS7状态栏的显隐/颜色 (0.149)
- 找到适合自己的前端发展方向 (0.149)
- 移动页面加速google的AMP和百度的MIP简介 (RANDOM - 0.149)
张鑫旭老师,请收下我的膝盖。
博主大人,有个问题提一下,就是那个.mask,我看了下源码,在Mobilebone.ajax方法里面执行完后就把.mask隐藏了,这个时候才开始页面切换的动画,而页面切换有个过程,在这个过程中,原来页面里的链接还是可以点击的,这个时候就会出现连续打开页面,如果这几个页面的url一样,只是参数不同的话,按返回键会发现先打开的那个页面会是空白的。
这样说吧,在a页面,有b、c两个链接,这两个链接只是参数不同,按mobilebone的逻辑,这两个链接的内容是放在同一个.page里的。
如果我点击了b,在b请求完毕后,.mask就隐藏了,如果在页面切换过程还没完成的时候,点击c,这个时候会又去加载c。
加载c以后,如果我点击返回,会回到b,但是页面是空白的了,再按一次返回,回到a是正常的
不知道我这样有没有描述明白?
我觉得可以把隐藏.mask的操作放在Mobilebone.transition方法执行完以后,不过另外.mask好像只会在页面第一次载入的时候才显示,这里应该还需要调整下
博主有意把这个跟WeUI结合起来吗?
感觉那套UI挺不错的
您好,感谢大神的框架,现在碰到一个问题,A页面跳转到B,B跳转到C,通过下面的方式跳转的:
Mobilebone.transition(pageB[0], pageA[0], false);
Mobilebone.transition(pageC[0], pageB[0], false);
现在在C页面点击浏览器的回退返回B页面,B页面的动画不是back,怎么处理?
博主,我用手机扫二维码 uc浏览器打开这个微信实例pageChatList到pageHome来回跳动会出现一个红色页面一闪, 而qq和微信 和电脑都没有.,.
我引用 mobilebone.css和mobilebone.js,
然后页面上的新闻 没有切换的效果啊,直接跳走了,着急,这是为什么
需要一定的HTML结构支持,检查下看看~
鑫哥,当我点击a标签跳转之后,新页面的$(function(){});里面的方法执行了,但是$(window).load(function);却没有执行,这是为何啊
http://linfaxin.com/AndroidUI4Web/sample/main.html#
试试看这个
今天刚看到的感觉更加接近native体验
张大神,非常感谢您的回复,但是还是希望有解决办法,下面是本人的理解,不知道对不对,$(window).load()是根据页面的body部分加载完成后执行的,引用mobilebone.js后,是body下面的page之间的切换,导致其他页面的body不加载,有办法让其他页面的$(window).load()执行吗?
张大神,mobilebone.js和$(window).load()冲突,导致$(window).load()不执行。这个有办法解决吗
@sq说说 应该不至于。主页面加载完毕,你再去请求其他页面,其他页面的$(window).load()自然不执行,与mobilebone.js无关。
已经解决,谢谢鑫哥!不过$(window).load();不执行是啥原因呢,神,回复我一下,让你的荣光普照大地
鑫哥,这个data-cellback回调函数是怎么执行的?是 然后 cellback:function(){ alert(“hello world”) }?
@wen data-callback的值是函数名称,你可以去几个test页面查看使用方法。
谢谢鑫哥,还有个小问题,当cellback回调函数成功执行后,我想向pageHome中的一个div插入一句话,源代码显示是插入成功了,但是页面并没有什么显示效果,我加上data-reload以后,也没啥效果,闲暇之余,请帮忙回答一下,谢谢!
@wen pageHome是隐藏的还是显示的,自己检查下吧~
由B页面返回A页面时,如何刷新A页面,还有乍样能不让JS自动缓存?请问如何解决,谢谢!!!
由B页面返回A页面时,乍样刷新A页面,急!!!
为啥跳转到另一个页面时js不加载,急!!!
@admin 其他页面的JS不加载,设计就是这样。防止公用JS重复加载执行。有参数evalScript设置,可以开启执行内联的script脚本。
能详细说说吗,比如我从A页面跳转到B页面,B页面需要加载自己的JS时,乍引用,还有从B页面返回到A页面时,A页面的JS也不加载了,这是啥原因了,请大神帮助!!!
如果为了防止公用JS重复加载执行就不加载其他页面的js了,这个会不会有因小失大的感觉?能不能改为在加载js的时候做个判断,如果已经加载了就不加载了
有API可以控制,evalScript,可以执行内联script.
当页面中嵌入iframe是,要返回两次,如何解决?
问个问题,在data-classpage内如何获取data-formdata的内容,用page我用获取浏览器地址的方式勉强解决了,但是data-classpage就不行了(浏览器地址没有改变)
请问下 这个插件在移动端手机上下滑动 来切换滑动页面??
看你展示的视频,页面切换貌似不太流畅?
您好,请教一下。我用mobilebone.js的同时,前端框架使用bootstrap、amazeui等,会有冲突吗?
@suxua31 一般是不会的
用了此插件,就没法用本身的锚点功能了。从A页到B页的某个锚点处,由于B页加了”page out”类,无法正确的到B页的锚点处。
Mobilebone.jsonHandle(json)这个方法能不能改一下多加几个参数比如把页面的信息或者ajax传的data参数放这里Mobilebone.jsonHandle(pagein, queryString||queryData, json);
张大神,我网站引用了zeopt,是不是会冲突,完全没效果了。
@sk 支持Zepto的,看看是不是其他处理touch事件的脚本造成的。
官网文档里面Mobilebone.rootTransition部分的解释有笔误,
FUN = {
home: function(pageInto, pageOut, response) {},
start: function(page, into_or_out) {},
end: function(page, into_or_out) {}
};
Mobilebone.captureLink = FUN;
是否应该为:
FUN = {
home: function(pageInto, pageOut, response) {},
start: function(page, into_or_out) {},
end: function(page, into_or_out) {}
};
Mobilebone.rootTransition= FUN;
切换为什么要点击两次才会有效果呢?
@ooo 应该与你使用的框架的tap事件有冲突原因造成的~
ajax 方式 点击a标签(a标签设置了 data-params 传递参数) 跳转到 b页面的时候,在用 globalObject.fun.xxxxx 回掉时,怎么获取 data-params设置 的参数呀
请问
通过 ajax 加载的页面,如何指定 data-form 过场动画呢?
3. 已知问题
一些老三星手机上,会出现第一次animation页面比例突然变小再恢复的诡异问题。希望有经验的朋友赐教!
对于这个问题,可以使用具体的宽高度值代替百分比来处理(这个在Android2.*版本比较常见,Android4.*之后基本上没有这个问题)
最近也有打算开源一个类似的框架。
这个问题我用Echart的时候也会出现,图表的宽设定成100%就会变成很窄,必须拉一下网页才能撑开,能不能解决掉这问题?
张总,框架很好用用的很开心.
http://h5.qian360.com/#&pageHome
还需要添加“阻止后退”的方法,可“拦截”,比如弹窗之后,希望后退键实现关闭弹窗、首页禁止后退
旭哥,把ajax的progress事件加上去呀!~页面加载的时候有个进度显示我觉得比较好啊~!
属于bug吗
1浏览器打开首页, history里没有首页记录
2.点击a打开aaa.html ,history 有aaa记录
3.如果在aaa中用 javascript:history.go(-1); 返回就会出错
4.如果直接点浏览器返回 ,ok的
用history.go(0);好了
点来点去 ,出现这个 . CAUTION: Provisional headers are shown
why not history.back()
我用图片做的两个页面 ,切换的时候闪屏.不知道该怎么处理.
不明白为什么我的 a 标签如果放在 .page 之外就不能点击了,这个是哪里控制的?
大神,js只能在首页上引用吗?
用ajax跳转的时候,从a.html跳转到b.html后,b.html的css以及js都失效了。
怎么解决,每个页面对应一个js毕竟维护起来好一点,如果把js和css放着div中又不好调试,求解
@cyclone77 你可以动态加载这些资源。
作者您好,您开发的这个框架我很喜欢,我把它应用在了公司的手机bbs社区中,用户体验非常赞.
但是有一个痛点让我不知如何是好,就是通过url传参的问题,每次当前页面的页面跳转都会把页面上的url干掉,导致第二个页面拿不到前面传过来的值.以至于为了这个需求维护了另外一个分支,为了实现这个需求,此时这个url已不符合http的书写规范了`http://bbs.qian360.com/app/#&pageBbsList?forumId=4&type=all`
鑫鑫同学有没有考虑过给骨头添加触控扩展,放在核心包之外,在移动端通过滑动过场是很常用的
你好,能否增强实现其它的手势用来过场?比如swipe等
@臭豆腐的 你好,不支持手势,也不会支持手势。你可以试试iscroll.
貌似加载动态页面的时候的这个过场顺序不对啊,应该是先过场然后再转菊花加载页面啊,你这是转菊花加载页面然后再过场!~
@reyhappen 都是可以的,看你怎么控制。
有必要补充一个智能返回上一页的事件来调用,目前的必须通过指定具体的链接返回很有局限性!
你好,我想问一下。。如果从a站的页面转向b站,a站没有用mobilebone,b站的返回按钮如何返回a站呢。
比如:一个页面里就有一个link,没加载任何其他内容,进入了加载mobilebone骨架的页面,之后如何返回呢?
返回操作是否可以做得更加智能,不需要指定href,目前指定href的方式有局限,比如商品列表到商品详情,搜索商品结果到商品详情,都是详情里面的返回,却要去处理到底返回到哪里!
你好,看了你的bone的test例子,有个疑问,ajax请求外部页面在纯html下是无法实现的,因为跨域问题,需要php创建个服务端情况下才能实现例子所有的ajax请求外部页面,我们在使用phonegap开发移动端的时候不是全都是html+js+css然后靠jsonp与php服务器做数据交换吗?难道需要在phonegap的html页面里面加载php页面来实现吗?新手问题请赐教,您在做phonegap应用时是访问php页面吗还是全纯html。
真的很兴奋看到国人做了自己的好用的js技术框架,我用了jquerymobile后直接放弃了,闪屏问题让我头疼不已,实际应用过程中发现一个问题,就是贵框架header 和 content footer是分离的在切换的时候是更新了content内容并通过参数修改了header title这样做的确很有优势,不像jqm那样page里面包含了header和footer,无法共用同一个header和footer,但是问题来了,如果我每个页面header都不一样,不仅仅标题不一样,header还带有其他的功能性按钮,该如何做呢,把header放在content里面吗?
你好,当点击某链接,尤其是动态append到页面的链接,使用click函数处理某些业务之后需要手动跳转到指定page,我使用Mobilebone.transition(‘pageHome’,”);函数怎么无效呢?也试过Mobilebone.transition(‘#pageHome’);难道不是用这个函数吗,
我之前发了个说 Mobilebone.transition(pageInto,pageOut);无效的疑问,是我自己弄错了,习惯了使用jqm和jquery,让我思维狭隘,这里pageInto,pageOut指的是dom元素,也就是这样
var pageInto=document.getElementById(“pageIntoId”);
var pageOut=document.getElementById(“pageOutId”);
Mobilebone.transition(pageInto,pageOut);
还是那么顺畅,感谢张 鑫旭,对了你这里怎么donate ,等我项目拿到钱一定支撑下
我想联系你请教几个问题,我做app应用使用bone和cordova,都是用本地html,jsonp负责数据,但我不可能将所有page都做到index.html里面实现无刷新切换,分成a.html,b.html后直接的跳转只能用原始链接 data-ajax=false ;但页面效果很差,难道只能都放到php服务器上加载吗?这样不是违背了html5在移动端的原则吗?请教该怎么处理不同hmtl页面之间的切换,本地的非部署到服务器上
把你要加载的页面加上id直接写在首页里就可以了!~然后点击哪个a链接跳转的就在那个a上加锚点链接地址~!
评论信息这里,怎么我填写了网址项,还是会提示请输入网址呢?
是不是这里的验证有问题?
感觉跟framework7类似,不过他们实现的更完善一些。
然而博主这个则更加请轻便,方便和其他框架进行配合。
浏览器再次刷新后,所有page全部都显示出来,一片混乱,怎么处理?
@明月 why, 默认page都有类名
out
都是隐藏的~在主页面(pageHome)的page添加out类,刷新之后就不出问题了。
我这样写的
可以实现过场的时候不“带走”前一个页面吗?而是将该页面保留在新页面的“下方”,这样我返回的时候的效果就是新页面向右离开,原页面直接在原位置显示。
@Jam 这个需求可以考虑下,目前只能通过在回调中做一些任性地处理实现。
可以考虑
请问,在应用中大量使用data-reload会否有性能问题?从源码上看,是将旧的页面给remove掉,那么这个页面所有资源是否有得到释放,事件是否都被注销?
比如,要实现a转场到b,b转场到c,c页面中包含很多到不同页面的链接,为了保持dom尽量轻量,打算把c里面的用到的转场都作为临时转场,不插入到history中,即点击c链接进入d或者e、f等,但是后退操作时d、e、f会在fallback时清理掉,此时history却做不到清理!这里为什么不能用data-container,主要还是考虑到此类情况还是要支持手机物理键、浏览器后退操作从d或e、f返回到c页面的!
1、如何由开发人员自主控制哪些a链接需要增加进历史记录?
2、如果是一些临时过场(不需要插入历史记录),即便在fallback时,将其dom移除,如何可以做到将其对于在history中历史记录一起移除,不然就会出现点击后退再点击前进时页面呈现空白!
3、使用Mobilebone.createPage创建页面,如果配置options.history为false,此时虽然当前过场不插入历史记录,但是此时点击手机后退物理键、或者浏览器后退,不是从当前不记录页面(临时过场页面)切换到上一个,而是直接在上一个页面切换到上上个页面,这点笔者可以试试,不合常理!
5、使用Mobilebone.ajax一样不能满足临时过场(不需要插入历史记录)的需求。
6、就目前Mobilebone没有好的方案来满足临时过场(不需要插入历史记录)的情况,建议支持,谢谢!
@xuetian120 试试使用
data-container
, 不会记录历史。Mobilebone.createPage的问题是个好反馈,我回头看看。data-container做的是内部切换,最大的问题不能支持手机物理键的后退操作!
实际场景就是有部分转场出现的页面,后退的时候转场离开,但是不需要记录在history中。这对于一些稍微复杂一点的应用,临时或者过程中出现的整屏page页面,很难满足到需求!
我也遇到了同样的问题,a页面通过transition传参跳转到b页面,为防止用户手贱刷新页面,导致传参的值丢失,我要做一个处理就是返回上一页.于是乎,我又调用transition回上一个页面. 从表面的展现来看是正常的,但是history记录上还是存了b页面的地址,返回到b页面并无卵用,要如何干掉它呢?
比如,要实现a转场到b,b转场到c,c页面中包含很多到不同页面的链接,为了保持dom尽量轻量,打算把c里面的用到的转场都作为临时转场,不插入到history中,即点击c链接进入d或者e、f等,但是后退操作时d、e、f会在fallback时清理掉,此时history却做不到清理!这里为什么不能用data-container,主要还是考虑到此类情况还是要支持手机物理键、浏览器后退操作从d或e、f返回到c页面的!
还有一个实际测试中遇到的情况,使用Mobilebone在华为荣耀6、魅蓝手机、三星部分机器上,所有的a连接触发的点击转场,整个延迟响应很大,大概2到3秒等无反应,在iPhone中转场响应则很快,但是如果直接绑定click事件则所有响应都很快,请笔者检查一下,注:使用了fastclick的基础上!
同样遇到这样的需求,我的处理方式是history.replaceState(null, null, targetPageUrl.replace(“#”, “index.html#&”));暂时这样混 着解决过去了
var noHistory = function (target) {
Mobilebone.transition($($(target).attr(“href”))[0], $(“.page.in”)[0], { history: false });
return true;
};
<a href=”#page2″ rel=”nofollow”>页面2</a>
data-preventdefault=”noHistory”