原創文章,歡迎轉載,轉載請註明出處。歡迎大家留言交流!
問題描述:
在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 期待遇到相同問題的朋友提供更好的方法。