原创文章,欢迎转载,转载请注明出处。欢迎大家留言交流!
问题描述:
在Hybrid App开发过程中,存在以下一种情况:当用户填写资料提交后,进入完成提示页。此时,用户点击返回键,又会返回到上一个提交资料页,用户可能会再次提交已经提交过的资料。这就导致了数据重复。
如:1.html(模块首页)—>2.html(提交资料页)—>3.html(完成提示页)
解决方案一:
在2.html中,当提交资料请求完成后,如果成功则在sessionStorage(关于sessionStorage的用法以及与localstorage的区别 )中设置一个键值对,(也可以在3.html中设置,都表示已成功提交)如下:
window.sessionStorage.setItem("buyStatus","true");
当在3.html按返回键时,返回到2.html。当2.html被加载时执行Js脚本
if(window.sessionStorage.getItem("buyStatus") == "true"){ window.history.go(-1); }
如果为条件true,则立即返回上一页(1.html)。这样就避免了用户在2.html中重复提交资料。当1.html被加载时,要清除这个状态。如下:
if(window.sessionStorage.getItem("buyStatus") == "true"){ window.sessionStorage.removeItem("buyStatus"); }— 优点:不需要修改native app里的代码。只需要修改web即可。 缺点:由于2.html中的返回脚本是在dom加载时执行的,实际效果是2.html展示后又立即关闭,所以该方法会给用户屏幕闪了一下的感觉,用户体验不太好。 ####解决方案二: 返回操作完全由web自己来控制,native app只是负责监测返回键事件。思路大概如下: 在web页面里提供goBack()方法和depth变量,在用户按返回键时,native app调用web里的goBack方法。goBack()的函数体如下:
//sys.js
var depth;
function goBack(){
window.history.go(depth);
}
具体实现如下: 1.html 2.html 3.html都引入了上边这个sys.js。这样3个文件都有了goBack()和depth变量。 在2.html中提交成功后进入3.html,在3.html中把depth赋值为-2。当按返回键时,android(ios)调用web的goBack方法:
/*android 代码*/ public void onBackPressed() { // super.onBackPressed(); if(webview.canGoBack()){ webview.loadUrl("javascript:goBack()"); }else { finish(); } } /*IOS代码*/ //todo 待补充
这样,web会直接从3.html返回到1.html。再按返回键就退出webview界面。
优点:navigate功能完全抽离到web端,便于实现以后更复杂导航功能。
缺点:1、如果你的工程以前不是这样做的,要改成这个模式的话。以前的所有页面都必须引入sys.js,并给depth赋恰当的值,如果页面太多,工作量也不小。 2、如果app需要展示一些再其他地方显示的页面(如微信里面的web),如果微信web没有sysjs,就会导致按返回键无响应的现象。针对这个现象的2个解决办法:
a、微信web的展示不再app里,而是调用系统默认浏览器打开。
b、app新建一个webview activity(webviewActivity2),该activity要处理返回键逻辑,如下:
public void onBackPressed() {
// super.onBackPressed();
if(webview.canGoBack()){
webview.goBack();
}else {
finish();
}
}
当在原webviewactivity的webviewclient的
shouldOverrideUrlLoading方法中检测到要跳转微信页面时,就跳转到webviewActivity2展示页面,这样当用户按返回键时就会执行上面的逻辑,native app会让web页面返回到上一个页面。
更好的方法:
//TODO 期待遇到相同问题的朋友提供更好的方法。