Hybrid交互设计研究
<p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">Hybrid交互设计</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">Hybrid的交互无非是Native调用前端页面的JS方法,或者前端页面通过JS调用Native提供的接口,两者交互的桥梁皆Webview:</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><img src="http://images2015.cnblogs.com/blog/294743/201510/294743-20151031114738779-2068756578.png" alt="" style="max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">app自身可以自定义url schema,并且把自定义的url注册在调度中心, 例如</p><ul style="padding-left: 30px; margin-top: 14px; margin-bottom: 14px; list-style-type: square; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><li>ctrip://wireless 打开携程App</li><li>weixin:// 打开微信</li></ul><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">我们JS与Native通信一般就是创建这类URL被Native捕获处理,后续也出现了其它前端调用Native的方式,但可以做底层封装使其透明化,所以重点以及是如何进行前端与Native的交互设计。</p><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">JS to Native</h2><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">Native在每个版本会提供一些API,前端会有一个对应的框架团队对其进行封装,释放业务接口。比如糯米对外的接口是这样的:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);">1</span> BNJS.http.get();<span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">向业务服务器拿请求据【1.0】 1.3版本接口有扩展</span><span style="color: rgb(0, 128, 128);">2</span> BNJS.http.post();<span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">向业务服务器提交数据【1.0】</span>
<span style="color: rgb(0, 128, 128);">3</span> BNJS.http.sign();<span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">计算签名【1.0】</span>
<span style="color: rgb(0, 128, 128);">4</span> BNJS.http.getNA();<span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">向NA服务器拿请求据【1.0】 1.3版本接口有扩展</span>
<span style="color: rgb(0, 128, 128);">5</span> BNJS.http.postNA();<span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">向NA服务器提交数据【1.0】</span>
<span style="color: rgb(0, 128, 128);">6</span> BNJS.http.getCatgData();<span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">从Native本地获取筛选数据【1.1】</span></pre></div><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);"> 1</span> BNJSReady(<span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">(){
</span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);"> BNJS.http.post({
</span><span style="color: rgb(0, 128, 128);"> 3</span> url : 'http://cp01-testing-tuan02.cp01.baidu.com:8087/naserver/user/feedback'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);"> params : {
</span><span style="color: rgb(0, 128, 128);"> 5</span> msg : '测试post'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 6</span> contact : '18721687903'
<span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);"> },
</span><span style="color: rgb(0, 128, 128);"> 8</span> onSuccess : <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">(res){
</span><span style="color: rgb(0, 128, 128);"> 9</span> alert('发送post请求成功!'<span style="color: rgb(0, 0, 0);">);
</span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);"> },
</span><span style="color: rgb(0, 128, 128);">11</span> onFail : <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">(res){
</span><span style="color: rgb(0, 128, 128);">12</span> alert('发送post请求失败!'<span style="color: rgb(0, 0, 0);">);
</span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);"> });
</span><span style="color: rgb(0, 128, 128);">15</span> });</pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">前端框架定义了一个全局变量BNJS作为Native与前端交互的对象,只要引入了糯米提供的这个JS库,并且在糯米封装的Webview容器中,前端便获得了调用Native的能力,我揣测糯米这种设计是因为这样便于第三方团队的接入使用,手机百度有一款轻应用框架也走的这种路线:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);">clouda.mbaas.account <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">释放了clouda全局变量</span></pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">这样做有一个前提是,<strong>Native本身已经十分稳定了</strong>,很少新增功能了,否则在直连情况下就会面临一个尴尬,因为web站点永远保持最新的,就会在一些低版本容器中调用了没有提供的Native能力而报错。</p><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">API式交互</h2><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">手白、糯米底层如何做我们无从得知,但我们发现调用Native API接口的方式和我们使用AJAX调用服务器端提供的接口是及其相似的:</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><img src="http://images2015.cnblogs.com/blog/294743/201510/294743-20151031144420904-967597577.jpg" alt="" style="max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">这里类似的微薄开放平台的接口是这样定义的:</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">粉丝服务(新手接入指南) 读取接口 接收消息 接收用户私信、关注、取消关注、@等消息接口 写入接口 发送消息 向用户回复私信消息接口 生成带参数的二维码 生成带参数的二维码接口</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">我们要做的就是通过一种方式创建ajax请求即可:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);">https:<span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">api.weibo.com/2/statuses/public_timeline.json</span></pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">所以我在实际设计Hybrid交互模型时,是以接口为单位进行设计的,比如获取通讯录的总体交互是:</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><img src="http://images2015.cnblogs.com/blog/294743/201510/294743-20151031145939029-1427658371.png" alt="" style="max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></p><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">格式约定</h2><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">交互的第一步是设计数据格式,这里分为请求数据格式与响应数据格式,参考ajax的请求模型大概是:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 0, 0);">$.ajax(options) ⇒ XMLHttpRequest
type (默认值:</span>"GET"<span style="color: rgb(0, 0, 0);">) HTTP的请求方法(“GET”, “POST”, or other)。
url (默认值:当前url) 请求的url地址。
data (默认值:none) 请求中包含的数据,对于GET请求来说,这是包含查询字符串的url地址,如果是包含的是object的话,$.param会将其转化成string。</span></pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">所以我这边与Native约定的请求模型是:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 0, 0);">requestHybrid({
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">创建一个新的webview对话框窗口</span>
tagname: 'hybridapi'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">请求参数,会被Native使用</span>
<span style="color: rgb(0, 0, 0);"> param: {},
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Native处理成功后回调前端的方法</span>
callback: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (data) {
}
});</span></pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">这个方法执行会形成一个URL,比如:</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">hybridschema://hybridapi?callback=hybrid_1446276509894&param=%7B%22data1%22%3A1%2C%22data2%22%3A2%7D</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">这里提一点,APP安装后会在手机上注册一个schema,比如淘宝是taobao://,Native会有一个进程监控Webview发出的所有schema://请求,然后分发到“控制器”hybridapi处理程序,Native控制器处理时会需要param提供的参数(encode过),处理结束后将携带数据获取Webview window对象中的callback(hybrid_1446276509894)调用之</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">数据返回的格式约定是:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 0, 0);">{
data: {},
errno: </span>0<span style="color: rgb(0, 0, 0);">,
msg: </span>"success"<span style="color: rgb(0, 0, 0);">
}</span></pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">真实的数据在data对象中,如果errno不为0的话,便需要提示msg,这里举个例子如果错误码1代表该接口需要升级app才能使用的话:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 0, 0);">{
data: {},
errno: </span>1<span style="color: rgb(0, 0, 0);">,
msg: </span>"APP版本过低,请升级APP版本"<span style="color: rgb(0, 0, 0);">
}</span></pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><strong>代码实现</strong></p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">这里给一个简单的代码实现,真实代码在APP中会有所变化:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);"> 1</span> window.Hybrid = window.Hybrid ||<span style="color: rgb(0, 0, 0);"> {};
</span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 255);">var</span> bridgePostMsg = <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (url) {
</span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> ($.os.ios) {
</span><span style="color: rgb(0, 128, 128);"> 4</span> window.location =<span style="color: rgb(0, 0, 0);"> url;
</span><span style="color: rgb(0, 128, 128);"> 5</span> } <span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {
</span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 255);">var</span> ifr = $(''<span style="color: rgb(0, 0, 0);">);
</span><span style="color: rgb(0, 128, 128);"> 7</span> $('body'<span style="color: rgb(0, 0, 0);">).append(ifr);
</span><span style="color: rgb(0, 128, 128);"> 8</span> setTimeout(<span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () {
</span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);"> ifr.remove();
</span><span style="color: rgb(0, 128, 128);">10</span> }, 1000<span style="color: rgb(0, 0, 0);">)
</span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">};
</span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 255);">var</span> _getHybridUrl = <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (params) {
</span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 255);">var</span> k, paramStr = '', url = 'scheme://'<span style="color: rgb(0, 0, 0);">;
</span><span style="color: rgb(0, 128, 128);">15</span> url += params.tagname + '?t=' + <span style="color: rgb(0, 0, 255);">new</span> Date().getTime(); <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">时间戳,防止url不起效</span>
<span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (params.callback) {
</span><span style="color: rgb(0, 128, 128);">17</span> url += '&callback=' +<span style="color: rgb(0, 0, 0);"> params.callback;
</span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 255);">delete</span><span style="color: rgb(0, 0, 0);"> params.callback;
</span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">20</span> <span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (params.param) {
</span><span style="color: rgb(0, 128, 128);">21</span> paramStr = <span style="color: rgb(0, 0, 255);">typeof</span> params.param == 'object' ?<span style="color: rgb(0, 0, 0);"> JSON.stringify(params.param) : params.param;
</span><span style="color: rgb(0, 128, 128);">22</span> url += '&param=' +<span style="color: rgb(0, 0, 0);"> encodeURIComponent(paramStr);
</span><span style="color: rgb(0, 128, 128);">23</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">24</span> <span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> url;
</span><span style="color: rgb(0, 128, 128);">25</span> <span style="color: rgb(0, 0, 0);">};
</span><span style="color: rgb(0, 128, 128);">26</span> <span style="color: rgb(0, 0, 255);">var</span> requestHybrid = <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (params) {
</span><span style="color: rgb(0, 128, 128);">27</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">生成唯一执行函数,执行后销毁</span>
<span style="color: rgb(0, 128, 128);">28</span> <span style="color: rgb(0, 0, 255);">var</span> tt = (<span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Date().getTime());
</span><span style="color: rgb(0, 128, 128);">29</span> <span style="color: rgb(0, 0, 255);">var</span> t = 'hybrid_' +<span style="color: rgb(0, 0, 0);"> tt;
</span><span style="color: rgb(0, 128, 128);">30</span> <span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);"> tmpFn;
</span><span style="color: rgb(0, 128, 128);">31</span>
<span style="color: rgb(0, 128, 128);">32</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">处理有回调的情况</span>
<span style="color: rgb(0, 128, 128);">33</span> <span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (params.callback) {
</span><span style="color: rgb(0, 128, 128);">34</span> tmpFn =<span style="color: rgb(0, 0, 0);"> params.callback;
</span><span style="color: rgb(0, 128, 128);">35</span> params.callback =<span style="color: rgb(0, 0, 0);"> t;
</span><span style="color: rgb(0, 128, 128);">36</span> window.Hybrid = <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (data) {
</span><span style="color: rgb(0, 128, 128);">37</span> <span style="color: rgb(0, 0, 0);"> tmpFn(data);
</span><span style="color: rgb(0, 128, 128);">38</span> <span style="color: rgb(0, 0, 255);">delete</span><span style="color: rgb(0, 0, 0);"> window.Hybrid;
</span><span style="color: rgb(0, 128, 128);">39</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">40</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">41</span> <span style="color: rgb(0, 0, 0);"> bridgePostMsg(_getHybridUrl(params));
</span><span style="color: rgb(0, 128, 128);">42</span> <span style="color: rgb(0, 0, 0);">};
</span><span style="color: rgb(0, 128, 128);">43</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">获取版本信息,约定APP的navigator.userAgent版本包含版本信息:scheme/xx.xx.xx</span>
<span style="color: rgb(0, 128, 128);">44</span> <span style="color: rgb(0, 0, 255);">var</span> getHybridInfo = <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () {
</span><span style="color: rgb(0, 128, 128);">45</span> <span style="color: rgb(0, 0, 255);">var</span> platform_version =<span style="color: rgb(0, 0, 0);"> {};
</span><span style="color: rgb(0, 128, 128);">46</span> <span style="color: rgb(0, 0, 255);">var</span> na =<span style="color: rgb(0, 0, 0);"> navigator.userAgent;
</span><span style="color: rgb(0, 128, 128);">47</span> <span style="color: rgb(0, 0, 255);">var</span> info = na.match(/scheme\/\d\.\d\.\d/<span style="color: rgb(0, 0, 0);">);
</span><span style="color: rgb(0, 128, 128);">48</span>
<span style="color: rgb(0, 128, 128);">49</span> <span style="color: rgb(0, 0, 255);">if</span> (info && info) {
</span><span style="color: rgb(0, 128, 128);">50</span> info = info.split('/'<span style="color: rgb(0, 0, 0);">);
</span><span style="color: rgb(0, 128, 128);">51</span> <span style="color: rgb(0, 0, 255);">if</span> (info && info.length == 2<span style="color: rgb(0, 0, 0);">) {
</span><span style="color: rgb(0, 128, 128);">52</span> platform_version.platform = info;
</span><span style="color: rgb(0, 128, 128);">53</span> platform_version.version = info;
</span><span style="color: rgb(0, 128, 128);">54</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">55</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">56</span> <span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> platform_version;
</span><span style="color: rgb(0, 128, 128);">57</span> };</pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">因为Native对于H5来是底层,框架&底层一般来说是不会关注业务实现的,所以真实业务中Native调用H5场景较少,这里不予关注了。</p><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">常用交互API</h2><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">良好的交互设计是成功的第一步,在真实业务开发中有一些API一定会用到。</p><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">跳转</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">跳转是Hybrid必用API之一,对前端来说有以下跳转:</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">① 页面内跳转,与Hybrid无关</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">② H5跳转Native界面</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">③ H5新开Webview跳转H5页面,一般为做页面动画切换</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">如果要使用动画,按业务来说有向前与向后两种,forward&back,所以约定如下,首先是H5跳Native某一个页面</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">H5跳Native页面</span>
<span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">=>baidubus://forward?t=1446297487682&param=%7B%22topage%22%3A%22home%22%2C%22type%22%3A%22h2n%22%2C%22data2%22%3A2%7D</span>
<span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);">requestHybrid({
</span><span style="color: rgb(0, 128, 128);"> 4</span> tagname: 'forward'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);"> param: {
</span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">要去到的页面</span>
<span style="color: rgb(0, 128, 128);"> 7</span> topage: 'home'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">跳转方式,H5跳Native</span>
<span style="color: rgb(0, 128, 128);"> 9</span> type: 'native'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">其它参数</span>
<span style="color: rgb(0, 128, 128);">11</span> data2: 2
<span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">13</span> });</pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">比如携程H5页面要去到酒店Native某一个页面可以这样:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">=>schema://forward?t=1446297653344&param=%7B%22topage%22%3A%22hotel%2Fdetail%20%20%22%2C%22type%22%3A%22h2n%22%2C%22id%22%3A20151031%7D</span>
<span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">requestHybrid({
</span><span style="color: rgb(0, 128, 128);"> 3</span> tagname: 'forward'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);"> param: {
</span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">要去到的页面</span>
<span style="color: rgb(0, 128, 128);"> 6</span> topage: 'hotel/detail'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">跳转方式,H5跳Native</span>
<span style="color: rgb(0, 128, 128);"> 8</span> type: 'native'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">其它参数</span>
<span style="color: rgb(0, 128, 128);">10</span> id: 20151031
<span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">12</span> });</pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">比如H5新开Webview的方式跳转H5页面便可以这样:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">requestHybrid({
</span><span style="color: rgb(0, 128, 128);"> 2</span> tagname: 'forward'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);"> param: {
</span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">要去到的页面,首先找到hotel频道,然后定位到detail模块</span>
<span style="color: rgb(0, 128, 128);"> 5</span> topage: 'hotel/detail '<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">跳转方式,H5新开Webview跳转,最后装载H5页面</span>
<span style="color: rgb(0, 128, 128);"> 7</span> type: 'webview'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">其它参数</span>
<span style="color: rgb(0, 128, 128);"> 9</span> id: 20151031
<span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">11</span> });</pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">back与forward一致,我们甚至会有animattype参数决定切换页面时的动画效果,真实使用时可能会封装全局方法略去tagname的细节,这时就和糯米对外释放的接口差不多了。</p><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">Header 组件的设计</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">最初我其实是抵制使用Native提供的UI组件的,尤其是Header,因为平台化后,Native每次改动都很慎重并且响应很慢,但是出于两点核心因素考虑,我基本放弃了抵抗:</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">① 其它主流容器都是这么做的,比如微信、手机百度、携程</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">② 没有header一旦网络出错出现白屏,APP将陷入假死状态,这是不可接受的,而一般的解决方案都太业务了</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">PS:Native吊起Native时,如果300ms没有响应需要出loading组件,避免白屏</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">因为H5站点本来就有Header组件,站在前端框架层来说,需要确保业务的代码是一致的,所有的差异需要在框架层做到透明化,简单来说Header的设计需要遵循:</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">① H5 header组件与Native提供的header组件使用调用层接口一致</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">② 前端框架层根据环境判断选择应该使用H5的header组件抑或Native的header组件</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">一般来说header组件需要完成以下功能:</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">① header左侧与右侧可配置,显示为文字或者图标(这里要求header实现主流图标,并且也可由业务控制图标),并需要控制其点击回调</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">② header的title可设置为单标题或者主标题、子标题类型,并且可配置lefticon与righticon(icon居中)</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">③ 满足一些特殊配置,比如标签类header</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">所以,站在前端业务方来说,header的使用方式为(其中tagname是不允许重复的):</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Native以及前端框架会对特殊tagname的标识做默认回调,如果未注册callback,或者点击回调callback无返回则执行默认方法</span>
<span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> back前端默认执行History.back,如果不可后退则回到指定URL,Native如果检测到不可后退则返回Naive大首页</span>
<span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> home前端默认返回指定URL,Native默认返回大首页</span>
<span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.header.set({
</span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);"> left: [
</span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);"> {
</span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">如果出现value字段,则默认不使用icon</span>
<span style="color: rgb(0, 128, 128);"> 8</span> tagname: 'back'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 9</span> value: '回退'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">如果设置了lefticon或者righticon,则显示icon</span>
<span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">native会提供常用图标icon映射,如果找不到,便会去当前业务频道专用目录获取图标</span>
<span style="color: rgb(0, 128, 128);">12</span> lefticon: 'back'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">13</span> callback: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () { }
</span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);"> ],
</span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);"> right: [
</span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);"> {
</span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">默认icon为tagname,这里为icon</span>
<span style="color: rgb(0, 128, 128);">19</span> tagname: 'search'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">20</span> callback: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () { }
</span><span style="color: rgb(0, 128, 128);">21</span> <span style="color: rgb(0, 0, 0);"> },
</span><span style="color: rgb(0, 128, 128);">22</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">自定义图标</span>
<span style="color: rgb(0, 128, 128);">23</span> <span style="color: rgb(0, 0, 0);"> {
</span><span style="color: rgb(0, 128, 128);">24</span> tagname: 'me'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">25</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">会去hotel频道存储静态header图标资源目录搜寻该图标,没有便使用默认图标</span>
<span style="color: rgb(0, 128, 128);">26</span> icon: 'hotel/me.png'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">27</span> callback: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () { }
</span><span style="color: rgb(0, 128, 128);">28</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">29</span> <span style="color: rgb(0, 0, 0);"> ],
</span><span style="color: rgb(0, 128, 128);">30</span> title: 'title'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">31</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">显示主标题,子标题的场景</span>
<span style="color: rgb(0, 128, 128);">32</span> title: ['title', 'subtitle'<span style="color: rgb(0, 0, 0);">],
</span><span style="color: rgb(0, 128, 128);">33</span>
<span style="color: rgb(0, 128, 128);">34</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">定制化title</span>
<span style="color: rgb(0, 128, 128);">35</span> <span style="color: rgb(0, 0, 0);"> title: {
</span><span style="color: rgb(0, 128, 128);">36</span> value: 'title'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">37</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">标题右边图标</span>
<span style="color: rgb(0, 128, 128);">38</span> righticon: 'down', <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">也可以设置lefticon</span>
<span style="color: rgb(0, 128, 128);">39</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">标题类型,默认为空,设置的话需要特殊处理</span>
<span style="color: rgb(0, 128, 128);">40</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">type: 'tabs',</span>
<span style="color: rgb(0, 128, 128);">41</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">点击标题时的回调,默认为空</span>
<span style="color: rgb(0, 128, 128);">42</span> callback: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () { }
</span><span style="color: rgb(0, 128, 128);">43</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">44</span> });</pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">因为Header左边一般来说只有一个按钮,所以其对象可以使用这种形式:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.header.set({
</span><span style="color: rgb(0, 128, 128);"> 2</span> back: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () { },
</span><span style="color: rgb(0, 128, 128);"> 3</span> title: ''
<span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);">});
</span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">语法糖=></span>
<span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.header.set({
</span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);"> left: [{
</span><span style="color: rgb(0, 128, 128);"> 8</span> tagname: 'back'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 9</span> callback: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">(){}
</span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);"> }],
</span><span style="color: rgb(0, 128, 128);">11</span> title: ''<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">12</span> });</pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">为完成Native端的实现,这里会新增两个接口,向Native注册事件,以及注销事件:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);">1</span> <span style="color: rgb(0, 0, 255);">var</span> registerHybridCallback = <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (ns, name, callback) {
</span><span style="color: rgb(0, 128, 128);">2</span> <span style="color: rgb(0, 0, 255);">if</span>(!window.Hybrid) window.Hybrid =<span style="color: rgb(0, 0, 0);"> {};
</span><span style="color: rgb(0, 128, 128);">3</span> window.Hybrid =<span style="color: rgb(0, 0, 0);"> callback;
</span><span style="color: rgb(0, 128, 128);">4</span> <span style="color: rgb(0, 0, 0);">};
</span><span style="color: rgb(0, 128, 128);">5</span>
<span style="color: rgb(0, 128, 128);">6</span> <span style="color: rgb(0, 0, 255);">var</span> unRegisterHybridCallback = <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (ns) {
</span><span style="color: rgb(0, 128, 128);">7</span> <span style="color: rgb(0, 0, 255);">if</span>(!window.Hybrid) <span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;
</span><span style="color: rgb(0, 128, 128);">8</span> <span style="color: rgb(0, 0, 255);">delete</span><span style="color: rgb(0, 0, 0);"> window.Hybrid;
</span><span style="color: rgb(0, 128, 128);">9</span> };</pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">Native Header组件的实现:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><div><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);"> 1</span> define([], <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () {
</span><span style="color: rgb(0, 128, 128);"> 2</span> 'use strict'<span style="color: rgb(0, 0, 0);">;
</span><span style="color: rgb(0, 128, 128);"> 3</span>
<span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> _.inherit({
</span><span style="color: rgb(0, 128, 128);"> 5</span>
<span style="color: rgb(0, 128, 128);"> 6</span> propertys: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () {
</span><span style="color: rgb(0, 128, 128);"> 7</span>
<span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 255);">this</span>.left =<span style="color: rgb(0, 0, 0);"> [];
</span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 255);">this</span>.right =<span style="color: rgb(0, 0, 0);"> [];
</span><span style="color: rgb(0, 128, 128);"> 10</span> <span style="color: rgb(0, 0, 255);">this</span>.title =<span style="color: rgb(0, 0, 0);"> {};
</span><span style="color: rgb(0, 128, 128);"> 11</span> <span style="color: rgb(0, 0, 255);">this</span>.view = <span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;
</span><span style="color: rgb(0, 128, 128);"> 12</span>
<span style="color: rgb(0, 128, 128);"> 13</span> <span style="color: rgb(0, 0, 255);">this</span>.hybridEventFlag = 'Header_Event'<span style="color: rgb(0, 0, 0);">;
</span><span style="color: rgb(0, 128, 128);"> 14</span>
<span style="color: rgb(0, 128, 128);"> 15</span> <span style="color: rgb(0, 0, 0);"> },
</span><span style="color: rgb(0, 128, 128);"> 16</span>
<span style="color: rgb(0, 128, 128);"> 17</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">全部更新</span>
<span style="color: rgb(0, 128, 128);"> 18</span> set: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (opts) {
</span><span style="color: rgb(0, 128, 128);"> 19</span> <span style="color: rgb(0, 0, 255);">if</span> (!opts) <span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;
</span><span style="color: rgb(0, 128, 128);"> 20</span>
<span style="color: rgb(0, 128, 128);"> 21</span> <span style="color: rgb(0, 0, 255);">var</span> left =<span style="color: rgb(0, 0, 0);"> [];
</span><span style="color: rgb(0, 128, 128);"> 22</span> <span style="color: rgb(0, 0, 255);">var</span> right =<span style="color: rgb(0, 0, 0);"> [];
</span><span style="color: rgb(0, 128, 128);"> 23</span> <span style="color: rgb(0, 0, 255);">var</span> title =<span style="color: rgb(0, 0, 0);"> {};
</span><span style="color: rgb(0, 128, 128);"> 24</span> <span style="color: rgb(0, 0, 255);">var</span> tmp =<span style="color: rgb(0, 0, 0);"> {};
</span><span style="color: rgb(0, 128, 128);"> 25</span>
<span style="color: rgb(0, 128, 128);"> 26</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">语法糖适配</span>
<span style="color: rgb(0, 128, 128);"> 27</span> <span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (opts.back) {
</span><span style="color: rgb(0, 128, 128);"> 28</span> tmp = { tagname: 'back'<span style="color: rgb(0, 0, 0);"> };
</span><span style="color: rgb(0, 128, 128);"> 29</span> <span style="color: rgb(0, 0, 255);">if</span> (<span style="color: rgb(0, 0, 255);">typeof</span> opts.back == 'string') tmp.value =<span style="color: rgb(0, 0, 0);"> opts.back;
</span><span style="color: rgb(0, 128, 128);"> 30</span> <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (<span style="color: rgb(0, 0, 255);">typeof</span> opts.back == 'function') tmp.callback =<span style="color: rgb(0, 0, 0);"> opts.back;
</span><span style="color: rgb(0, 128, 128);"> 31</span> <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (<span style="color: rgb(0, 0, 255);">typeof</span> opts.back == 'object'<span style="color: rgb(0, 0, 0);">) _.extend(tmp, opts.back);
</span><span style="color: rgb(0, 128, 128);"> 32</span> <span style="color: rgb(0, 0, 0);"> left.push(tmp);
</span><span style="color: rgb(0, 128, 128);"> 33</span> } <span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {
</span><span style="color: rgb(0, 128, 128);"> 34</span> <span style="color: rgb(0, 0, 255);">if</span> (opts.left) left =<span style="color: rgb(0, 0, 0);"> opts.left;
</span><span style="color: rgb(0, 128, 128);"> 35</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);"> 36</span>
<span style="color: rgb(0, 128, 128);"> 37</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">右边按钮必须保持数据一致性</span>
<span style="color: rgb(0, 128, 128);"> 38</span> <span style="color: rgb(0, 0, 255);">if</span> (<span style="color: rgb(0, 0, 255);">typeof</span> opts.right == 'object' && opts.right.length) right =<span style="color: rgb(0, 0, 0);"> opts.right
</span><span style="color: rgb(0, 128, 128);"> 39</span>
<span style="color: rgb(0, 128, 128);"> 40</span> <span style="color: rgb(0, 0, 255);">if</span> (<span style="color: rgb(0, 0, 255);">typeof</span> opts.title == 'string'<span style="color: rgb(0, 0, 0);">) {
</span><span style="color: rgb(0, 128, 128);"> 41</span> title.title =<span style="color: rgb(0, 0, 0);"> opts.title;
</span><span style="color: rgb(0, 128, 128);"> 42</span> } <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (_.isArray(opts.title) && opts.title.length > 1<span style="color: rgb(0, 0, 0);">) {
</span><span style="color: rgb(0, 128, 128);"> 43</span> title.title = opts.title;
</span><span style="color: rgb(0, 128, 128);"> 44</span> title.subtitle = opts.title;
</span><span style="color: rgb(0, 128, 128);"> 45</span> } <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (<span style="color: rgb(0, 0, 255);">typeof</span> opts.title == 'object'<span style="color: rgb(0, 0, 0);">) {
</span><span style="color: rgb(0, 128, 128);"> 46</span> <span style="color: rgb(0, 0, 0);"> _.extend(title, opts.title);
</span><span style="color: rgb(0, 128, 128);"> 47</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);"> 48</span>
<span style="color: rgb(0, 128, 128);"> 49</span> <span style="color: rgb(0, 0, 255);">this</span>.left =<span style="color: rgb(0, 0, 0);"> left;
</span><span style="color: rgb(0, 128, 128);"> 50</span> <span style="color: rgb(0, 0, 255);">this</span>.right =<span style="color: rgb(0, 0, 0);"> right;
</span><span style="color: rgb(0, 128, 128);"> 51</span> <span style="color: rgb(0, 0, 255);">this</span>.title =<span style="color: rgb(0, 0, 0);"> title;
</span><span style="color: rgb(0, 128, 128);"> 52</span> <span style="color: rgb(0, 0, 255);">this</span>.view =<span style="color: rgb(0, 0, 0);"> opts.view;
</span><span style="color: rgb(0, 128, 128);"> 53</span>
<span style="color: rgb(0, 128, 128);"> 54</span> <span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.registerEvents();
</span><span style="color: rgb(0, 128, 128);"> 55</span>
<span style="color: rgb(0, 128, 128);"> 56</span> <span style="color: rgb(0, 0, 0);"> _.requestHybrid({
</span><span style="color: rgb(0, 128, 128);"> 57</span> tagname: 'updateheader'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 58</span> <span style="color: rgb(0, 0, 0);"> param: {
</span><span style="color: rgb(0, 128, 128);"> 59</span> left: <span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.left,
</span><span style="color: rgb(0, 128, 128);"> 60</span> right: <span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.right,
</span><span style="color: rgb(0, 128, 128);"> 61</span> title: <span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.title
</span><span style="color: rgb(0, 128, 128);"> 62</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);"> 63</span> <span style="color: rgb(0, 0, 0);"> });
</span><span style="color: rgb(0, 128, 128);"> 64</span>
<span style="color: rgb(0, 128, 128);"> 65</span> <span style="color: rgb(0, 0, 0);"> },
</span><span style="color: rgb(0, 128, 128);"> 66</span>
<span style="color: rgb(0, 128, 128);"> 67</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">注册事件,将事件存于本地</span>
<span style="color: rgb(0, 128, 128);"> 68</span> registerEvents: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () {
</span><span style="color: rgb(0, 128, 128);"> 69</span> _.unRegisterHybridCallback(<span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.hybridEventFlag);
</span><span style="color: rgb(0, 128, 128);"> 70</span> <span style="color: rgb(0, 0, 255);">this</span>._addEvent(<span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.left);
</span><span style="color: rgb(0, 128, 128);"> 71</span> <span style="color: rgb(0, 0, 255);">this</span>._addEvent(<span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.right);
</span><span style="color: rgb(0, 128, 128);"> 72</span> <span style="color: rgb(0, 0, 255);">this</span>._addEvent(<span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.title);
</span><span style="color: rgb(0, 128, 128);"> 73</span> <span style="color: rgb(0, 0, 0);"> },
</span><span style="color: rgb(0, 128, 128);"> 74</span>
<span style="color: rgb(0, 128, 128);"> 75</span> _addEvent: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (data) {
</span><span style="color: rgb(0, 128, 128);"> 76</span> <span style="color: rgb(0, 0, 255);">if</span> (!_.isArray(data)) data =<span style="color: rgb(0, 0, 0);"> ;
</span><span style="color: rgb(0, 128, 128);"> 77</span> <span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);"> i, len, tmp, fn, tagname;
</span><span style="color: rgb(0, 128, 128);"> 78</span> <span style="color: rgb(0, 0, 255);">var</span> t = 'header_' + (<span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Date().getTime());
</span><span style="color: rgb(0, 128, 128);"> 79</span>
<span style="color: rgb(0, 128, 128);"> 80</span> <span style="color: rgb(0, 0, 255);">for</span> (i = 0, len = data.length; i < len; i++<span style="color: rgb(0, 0, 0);">) {
</span><span style="color: rgb(0, 128, 128);"> 81</span> tmp =<span style="color: rgb(0, 0, 0);"> data;
</span><span style="color: rgb(0, 128, 128);"> 82</span> tagname = tmp.tagname || ''<span style="color: rgb(0, 0, 0);">;
</span><span style="color: rgb(0, 128, 128);"> 83</span> <span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (tmp.callback) {
</span><span style="color: rgb(0, 128, 128);"> 84</span> fn = $.proxy(tmp.callback, <span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.view);
</span><span style="color: rgb(0, 128, 128);"> 85</span> tmp.callback =<span style="color: rgb(0, 0, 0);"> t;
</span><span style="color: rgb(0, 128, 128);"> 86</span> _.registerHeaderCallback(<span style="color: rgb(0, 0, 255);">this</span>.hybridEventFlag, t + '_' +<span style="color: rgb(0, 0, 0);"> tagname, fn);
</span><span style="color: rgb(0, 128, 128);"> 87</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);"> 88</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);"> 89</span> <span style="color: rgb(0, 0, 0);"> },
</span><span style="color: rgb(0, 128, 128);"> 90</span>
<span style="color: rgb(0, 128, 128);"> 91</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">显示header</span>
<span style="color: rgb(0, 128, 128);"> 92</span> show: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () {
</span><span style="color: rgb(0, 128, 128);"> 93</span> <span style="color: rgb(0, 0, 0);"> _.requestHybrid({
</span><span style="color: rgb(0, 128, 128);"> 94</span> tagname: 'showheader'
<span style="color: rgb(0, 128, 128);"> 95</span> <span style="color: rgb(0, 0, 0);"> });
</span><span style="color: rgb(0, 128, 128);"> 96</span> <span style="color: rgb(0, 0, 0);"> },
</span><span style="color: rgb(0, 128, 128);"> 97</span>
<span style="color: rgb(0, 128, 128);"> 98</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">隐藏header</span>
<span style="color: rgb(0, 128, 128);"> 99</span> hide: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () {
</span><span style="color: rgb(0, 128, 128);">100</span> <span style="color: rgb(0, 0, 0);"> _.requestHybrid({
</span><span style="color: rgb(0, 128, 128);">101</span> tagname: 'hideheader'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">102</span> <span style="color: rgb(0, 0, 0);"> param: {
</span><span style="color: rgb(0, 128, 128);">103</span> animate: <span style="color: rgb(0, 0, 255);">true</span>
<span style="color: rgb(0, 128, 128);">104</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">105</span> <span style="color: rgb(0, 0, 0);"> });
</span><span style="color: rgb(0, 128, 128);">106</span> <span style="color: rgb(0, 0, 0);"> },
</span><span style="color: rgb(0, 128, 128);">107</span>
<span style="color: rgb(0, 128, 128);">108</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">只更新title,不重置事件,不对header其它地方造成变化,仅仅最简单的header能如此操作</span>
<span style="color: rgb(0, 128, 128);">109</span> update: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (title) {
</span><span style="color: rgb(0, 128, 128);">110</span> <span style="color: rgb(0, 0, 0);"> _.requestHybrid({
</span><span style="color: rgb(0, 128, 128);">111</span> tagname: 'updateheadertitle'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">112</span> <span style="color: rgb(0, 0, 0);"> param: {
</span><span style="color: rgb(0, 128, 128);">113</span> title: 'aaaaa'
<span style="color: rgb(0, 128, 128);">114</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">115</span> <span style="color: rgb(0, 0, 0);"> });
</span><span style="color: rgb(0, 128, 128);">116</span> <span style="color: rgb(0, 0, 0);"> },
</span><span style="color: rgb(0, 128, 128);">117</span>
<span style="color: rgb(0, 128, 128);">118</span> initialize: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () {
</span><span style="color: rgb(0, 128, 128);">119</span> <span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.propertys();
</span><span style="color: rgb(0, 128, 128);">120</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">121</span> <span style="color: rgb(0, 0, 0);"> });
</span><span style="color: rgb(0, 128, 128);">122</span>
<span style="color: rgb(0, 128, 128);">123</span> });</pre></div>Native Header组件的封装</div><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">请求类</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">虽然get类请求可以用jsonp的方式绕过跨域问题,但是post请求却是真正的拦路虎,为了安全性服务器设置cors会仅仅针对几个域名,Hybrid内嵌静态资源是通过file的方式读取,这种场景使用cors就不好使了,所以每个请求需要经过Native做一层代理发出去。</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><img src="http://images2015.cnblogs.com/blog/294743/201511/294743-20151101171145060-1918906295.jpg" alt="" style="max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">这个使用场景与Header组件一致,前端框架层必须做到对业务透明化,业务事实上不必关心这个请求是由浏览器发出还是由Native发出:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);">1</span> HybridGet = <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (url, param, callback) {
</span><span style="color: rgb(0, 128, 128);">2</span> <span style="color: rgb(0, 0, 0);">};
</span><span style="color: rgb(0, 128, 128);">3</span> HybridPost = <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (url, param, callback) {
</span><span style="color: rgb(0, 128, 128);">4</span> };</pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">真实的业务场景,会将之封装到数据请求模块,在底层做适配,在H5站点下使用ajax请求,在Native内嵌时使用代理发出,与Native的约定为:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">requestHybrid({
</span><span style="color: rgb(0, 128, 128);"> 2</span> tagname: 'ajax'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);"> param: {
</span><span style="color: rgb(0, 128, 128);"> 4</span> url: 'hotel/detail'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);"> param: {},
</span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">默认为get</span>
<span style="color: rgb(0, 128, 128);"> 7</span> type: 'post'
<span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);"> },
</span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">响应后的回调</span>
<span style="color: rgb(0, 128, 128);">10</span> callback: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> (data) { }
</span><span style="color: rgb(0, 128, 128);">11</span> });</pre></div><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">常用NativeUI组件</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">最后,Native会提供几个常用的Native级别的UI,比如loading加载层,比如toast消息框:</p><div style="color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><pre style="font-family: consolas, monaco, menlo, "courier new", courier, monospace; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; padding: 6px 10px; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 255);">var</span> HybridUI =<span style="color: rgb(0, 0, 0);"> {};
</span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">HybridUI.showLoading();
</span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">=></span>
<span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);">requestHybrid({
</span><span style="color: rgb(0, 128, 128);"> 5</span> tagname: 'showLoading'
<span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">});
</span><span style="color: rgb(0, 128, 128);"> 7</span>
<span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">HybridUI.showToast({
</span><span style="color: rgb(0, 128, 128);"> 9</span> title: '111'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">几秒后自动关闭提示框,-1需要点击才会关闭</span>
<span style="color: rgb(0, 128, 128);">11</span> hidesec: 3<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">弹出层关闭时的回调</span>
<span style="color: rgb(0, 128, 128);">13</span> callback: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () { }
</span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);">});
</span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">=></span>
<span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);">requestHybrid({
</span><span style="color: rgb(0, 128, 128);">17</span> tagname: 'showToast'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);"> param: {
</span><span style="color: rgb(0, 128, 128);">19</span> title: '111'<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">20</span> hidesec: 3<span style="color: rgb(0, 0, 0);">,
</span><span style="color: rgb(0, 128, 128);">21</span> callback: <span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);"> () { }
</span><span style="color: rgb(0, 128, 128);">22</span> <span style="color: rgb(0, 0, 0);"> }
</span><span style="color: rgb(0, 128, 128);">23</span> });</pre></div><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">Native UI与前端UI不容易打通,所以在真实业务开发过程中,一般只会使用几个关键的Native UI。</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">来源:http://div.io/topic/1447</p><p></p> 浅谈Hybrid技术的设计与实现
http://www.cnblogs.com/yexiaochai/p/4921635.html
页:
[1]