这里back在webview中会检查history的记录,如果大于1则后退,否则会退回上一步操作。我们可以看出,back的功能是很单一的,往往不能满足我们的需求,所以常常使用forward+pop动画当做back使用,而这一做法将引起令人头疼的history错乱问题!!!
forwardforward是非常重要的一个API,在Hybrid中情况又比较复杂,所以这块要花点力气多思考,设计的好不好直接影响业务开发的接受情感。
我之前做框架时会禁止业务开发使用label标签与a标签,这个举动也受到了一些质疑(往往是语义化) 其实并不是label标签和a标签不好,而是解决移动端300ms延迟可能会对label标签做特殊处理,容易引起一些莫名其妙的BUG; 而a标签更是破坏单页应用路由的最佳选手,很多同事为a标签添加点击事件(没有设置href)又没有阻止默认事件而导致意想不到的BUG 像这种时候,你与其给人一个个解释要如何做特殊处理,倒不如直接禁止他们使用来得快......
H5跳NativeH5跳Native比较简单,只需要与Native同事约定topage的页面即可
1 requestHybrid({ 2 tagname: 'forward', 3 param: { 4 topage: 'index2', 5 type: 'native' 6 } 7 });
如果要带参数的话,便直接写到topage后面的参数上:
topage: 'index2?a=1&b=2',
这个写法显然是有点怪的,因为我们之前跳转是这样写的:
this.forward('index2', { a: 1, b: 2 });
为了保证业务代码一致,我们只需要在前端底层封装forward方法即可,这个将生成这种url,根据我们url schema的约定,这个链接就会进入到Native对应页面:
hybrid://forward?param=%7B%22topage%22%3A%22index2%22%2C%22type%22%3A%22native%22%7D
H5新开Webview跳H5本来H5跳H5走的是浏览器内部体系,但为增强体验会新开一个Webview做动画,尽可能的模拟Native交互,这个代码是这样的:
requestHybrid({ tagname: 'forward', param: { topage: 'flight/index.html', type: 'h5' } });
如果一个团队前端成体系的话,一般每个频道的代码是有规则的,一般是频道名/页面名,事实上每个topage都应该是一个完整的http的链接(如果前端传过去不是完整的,就需要Native补齐),这个也会封装到前端底层形成一个语法糖:
1 this.forward('flight/detail', {id: 1}) requestHybrid({ 4 tagname: 'forward', 5 param: { 6 topage: 'http://domain.com/webapp/flight/detail.html?id=1', 7 type: 'h5' 8 } 9 });
这个是针对线上的场景,而如果读取的是内嵌资源的话就不是这么回事了,比如之前的代码:
1 requestHybrid({ 2 tagname: 'forward', 3 param: { 4 topage: 'flight/detail.html?id=1', 5 type: 'h5' 6 } 7 });
这个是告诉Native去静态资源flight目录找寻detail.html然后载入,这里又涉及到一个问题是:业务到底该怎么写代码?因为很多时候我们是一套H5代码浏览器与Native两边运行,而我如果在H5想从首页到列表页直接这样写就行了:
this.forward('list', {id: 1})
业务是绝不希望这个代码要因为接入Hybrid而改变,就算业务开发接受,也会因为跳转选择而导致业务混乱引发各种问题,所以前端框架层要解决这个问题,保证业务最小程度的犯错几率,上面之所以不传完整http的链接给Native,是因为会有静态资源内嵌Native的场景,请看下面的例子:
requestHybrid({ tagname: 'forward', param: { //Native首先检查本地有没有这个文件,如果有就直接读取本地,没有就走http topage: 'flight/index.html', type: 'native' } });
这里为解决快速渲染提出了第一个约定:
跳转时,需要Native去解析URL,判断是否有本地文件,如果有则加载本地文件
举个例子来说:
http://domain.com/webapp/flight/index.html //解析url得出关键词 //===> flight/index.html 检查本地是否有该文件,有便直接返回
有这个规则的话,就可以最大程度上保证业务代码的一致性,而读取本地文件也能大大提高性能,缓存这块我们后面再说。
history错乱前面说了History错乱的原因一般来说是因为使用了forward模拟back回退,这种业务场景经常发生:
① 订单填写页需要去支付页面,由于一些特殊业务需求,需要经过一个中间页做处理,然后再进入真正的支付页,这个时候支付页点击后退事实上是执行的forward的操作(因为点击回退就到中间页了)
② 发布产品的时候会有发布1->发布2->发布预览->完成->产品详情页,这个时候点击产品详情页的后退,我们也不会希望他回到发布预览页,而是首页
③ 有可能用户直接由浏览器直接打开APP进入产品详情页,这个时候点击后退是没有任何记录的,当然也是回到首页了。