Hbuilder WebView 關於APP中的頁面返回問題 plus.webview
前言:
最近在做一個react+ant+H5app的APP應用項目。
眾所周知,應create-react-app腳手架創建出來的是單頁面項目。
在瀏覽器中,頁面通過react-router-dom進行組件渲染,從而看起來像是跳轉了頁面,利用history進行地址返回,看起來就像返回頁面一樣。
但是當react代碼開發完了,打包到H5+app中作為app時,在任何一個界面的返回都會直接退出APP應用,而不是像我們想的,從哪個頁面進來,就退出到那個界面中去。
按照我個人的理解和猜測,這是因為:react代碼部分是單頁面的,所以在app中,用react router跳轉的每一個頁面實際上都是index.html這個頁面,所以,看到的所有頁面按下返回鍵,都是直接退出應用。
那么,如何才能讓app的頁面像瀏覽器一樣,按下返回鍵就是返回到上一個頁面呢?
解決方法可能有很多種,但是我學術簡陋,只找到一種方法,那就是利用H5+APP的API plus.webview
一、路由與webview說明
- HashRouter用於分配url,如
【/index,/scan,/boxMessage。。。】 - webview用於APP的頁面新建和跳轉,如
【createWebview('http://xxxx:xxxx/#/edictor?sendData=' + jsonsendData, 'edictor_scan_add','添加數據')】
二、頁面跳轉邏輯
我做過的一個react app 項目的webview邏輯
0.目前webview共6個
【scan】從首頁創建的掃碼頁面
【edictor_index_change】從主頁創建的修改數據界面
【boxMessage】從掃碼頁創建的盒子信息界面
【edictor_scan_add】從掃碼頁創建的添加信息界面
【edictor_box_add】從盒子頁創建的添加信息界面
【edictor_box_change】從盒子頁創建的修改數據界面
1.從首頁點擊修改按鈕 跳轉到編輯頁面進行數據修改
【1首 =》編(修改) 1.首頁建編寫頁面】
【1首 =》編(修改) 2.編寫頁面關閉】
【1首 =》編(修改) 3.首頁捕獲編輯界面關閉后刷新首頁】
2.從首頁點擊掃碼 並且所掃二維碼是之前未掃過的,跳轉到新建頁面 進行盒子的機床信息新建
【2首 =》掃 =》編(新建) 1.首頁建掃描頁面】
【2首 =》掃 =》編(新建) 2.掃描頁建編輯頁面】
【2首 =》掃 =》編(新建) 3.編寫頁面關閉跳到掃面頁面】
【2首 =》掃 =》編(新建) 4.掃描頁面捕獲編輯界面的關閉事件后 關閉掃描頁面】
【2首 =》掃 =》編(新建) 5.首頁捕獲掃描頁面的關閉后 刷新首頁】
3.從首頁點擊掃碼 並且所掃二維碼是值卡掃過的,跳轉的這個盒子的信息界面 進一步進行繼續添加盒子機床信息,或者修改某一條盒子機床信息(下邊有例子)
【3首 =》掃 =》盒 =》編(從盒子到編輯) 1.首頁建掃描頁面】
【3首 =》掃 =》盒 =》編(從盒子到編輯) 2.掃面頁創建盒子頁】
【3首 =》掃 =》盒 =》編(從盒子到編輯) 3.盒子頁創建編輯頁(修改)】
【3首 =》掃 =》盒 =》編(從盒子到編輯) 4.編輯頁關閉跳到盒子頁】
【3首 =》掃 =》盒 =》編(從盒子到編輯) 5.盒子頁檢測到編輯頁關閉后 刷新盒子界面(修改)】
【3首 =》掃 =》盒 =》編(從盒子到編輯) 6.掃描界面檢測到盒子界面關閉后 關閉掃描界面】
【3首 =》掃 =》盒 =》編(從盒子到編輯) 7.首頁檢測到掃描界面關閉后 刷新首頁】
4.當在某個盒子信息界面中,刪除了該盒子對應的所有機床信息后,界面自動跳轉回首頁
【4首 =》掃 =》盒 =》首(盒子數據刪完) 1.首頁建掃描頁面】
【4首 =》掃 =》盒 =》首(盒子數據刪完) 2.掃面頁創建盒子頁】
【4首 =》掃 =》盒 =》首(盒子數據刪完) 3.盒子頁關閉】
【4首 =》掃 =》盒 =》首(盒子數據刪完) 4.掃描界面檢測到盒子界面關閉后 關閉掃描界面】
【4首 =》掃 =》盒 =》首(盒子數據刪完) 5.首頁檢測到掃描界面關閉后 刷新首頁】
三、webview使用示例
方法舉例:從首頁點擊掃碼 並且所掃二維碼是值卡掃過的,跳轉的這個盒子的信息界面 進一步進行繼續添加盒子機床信息,或者修改某一條盒子機床信息
步驟1、7 #index首頁
// 掃碼
qrHandle = () => {
const that = this
// 【3首=》掃=》盒=》編(從盒子到編輯) 1.首頁建掃描頁面】
if (_openw) { return } // 防止快速點擊
// _openw = createWebview('http://xxxx:9000/#/scan','scan','掃碼')
_openw = createWebview('http://xxxx:9000/#/scan','scan','掃碼')
_openw.addEventListener('loaded', function () {//頁面加載完成后才顯示
_openw && _openw.show('zoom-fade-out', null, function () {
_openw = null//避免快速點擊打開多個頁面
})
}, false)
_openw.addEventListener('hide', function () {
_openw = null
}, false)
_openw.addEventListener('close', function () {//頁面關閉后可再次打開
_openw = null
// 【3首=》掃=》盒=》編(從盒子到編輯) 7.首頁檢測到掃描界面關閉后 刷新首頁】
that.componentDidMount()
}, false)
}
步驟2、6 #scan掃碼
if (_openw) { return } // 防止快速點擊
// 【3首=》掃=》盒=》編(從盒子到編輯) 2.掃面頁創建盒子頁】
const resultTemp = encodeURI(result)
_openw = createWebview('http://xxxx:9000/#/boxMessage?sendData=' + resultTemp, 'boxMessage','盒子數據')
_openw.addEventListener('loaded', function () {//頁面加載完成后才顯示
_openw && _openw.show('pop-in', null, function () {
_openw = null//避免快速點擊打開多個頁面
})
}, false)
_openw.addEventListener('hide', function () {
_openw = null
}, false)
_openw.addEventListener('close', function () {//頁面關閉后可再次打開
_openw = null
// 【3首=》掃=》盒=》編(從盒子到編輯) 6.掃描界面檢測到盒子界面關閉后 關閉掃描界面】
plus.webview.close(thisWebView)
}, false)
步驟3、5 #boxMessage盒子頁
// 添加盒子信息按鈕
addData = () => {
const that = this
const sendData = {
boxId: this.state.boxIdMessage[0].boxId,
flag: "add",
from: 'boxMessage'
}
let jsonsendDataTemp = JSON.stringify(sendData)
let jsonsendData = encodeURI(jsonsendDataTemp)
// 【3首=》掃=》盒=》編(從盒子到編輯) 3.盒子頁創建編輯頁(添加)】
if (_openw) { return } // 防止快速點擊
_openw = createWebview('http://xxxx:9000/#/edictor?sendData=' + jsonsendData, 'edictor_box_add','添加數據')
_openw.addEventListener('loaded', function () {//頁面加載完成后才顯示
_openw && _openw.show('pop-in', null, function () {
_openw = null//避免快速點擊打開多個頁面
})
}, false)
_openw.addEventListener('hide', function () {
_openw = null
}, false)
_openw.addEventListener('close', function () {//頁面關閉后可再次打開
_openw = null
// 【3首=》掃=》盒=》編(從盒子到編輯) 5.盒子頁檢測到編輯頁關閉后 刷新盒子界面(添加)】
that.componentDidMount()
}, false)
}
步驟4 #edictor 編輯頁
if (from === 'boxMessage') {
// 【3首=》掃=》盒=》編(從盒子到編輯) 4.編輯頁關閉跳到盒子頁】
plus.webview.close(thisWebView)
四、webview的創建方法
注意:webview的創建需要放在plusready環境中
plus.webview.create(url, id, {
scrollIndicator: 'none',//是否顯示滾動條
scalable: false,//窗口是否可縮放
popGesture: 'close',//)窗口的側滑返回功能
backButtonAutoControl: 'close',//點擊上面返回按鈕時 是關閉頁面的效果
titleNView: {
autoBackButton: true,
backgroundColor: '#108ee9',
titleColor: '#fff',
titleText: text
}
})
}
五、webview的返回
0、在創建頁面時,設置返回邏輯
backButtonAutoControl: (String 類型 )Webview窗口自動處理返回鍵邏輯
當Webview窗口在顯示棧頂,並且Webview窗口中沒有調用JS監聽返回鍵(plus.key.addEventListener('backbutton',...))時按下返回鍵響應行為。
可取值:
"hide" - 隱藏Webview窗口,隱藏動畫與上一次調用顯示時設置的動畫類型相對應(如“slide-in-right”對應的關閉動畫為“slid-out-right”);
"close" - 關閉Webview窗口,關閉動畫與上一次調用顯示時設置的動畫類型相對應(如“slide-in-right”對應的關閉動畫為“slid-out-right”) ;
"none" - 不做操作,將返回鍵傳遞給下一Webview窗口處理; "quit" - 退出應用。
1、子頁面中的返回(當創建webview時沒有設置返回按鈕的效果,需要監聽backbutton(可在創造頁面的那個頁面寫(newWebview),也可以在本身頁面寫(currentWebview)))
document.addEventListener('plusready', function() {
const webview = plus.webview.currentWebview();//獲取這頁
plus.key.addEventListener('backbutton', function() {//監聽這頁的返回按鈕
webview.canBack(function(e) {//看看這也是否可以返回
if(e.canBack) {//如果可以返回
//webview.back();//回退;
} else {
webview.close(); //關閉這頁
//plus.runtime.quit();//退出app
}
})
});
})
2、首頁點擊兩次退出程序
document.addEventListener('plusready', function(a) {
var first = null;
plus.key.addEventListener('backbutton', function() {
//首次按鍵,提示‘再按一次退出應用’
if (!first) {
first = new Date().getTime();
plus.nativeUI.toast('再按一次退出應用')
setTimeout(function() {
first = null;
}, 2000);
} else {
if (new Date().getTime() - first < 2000) {
plus.runtime.quit();
}
}
}, false);
});
六、webview綜合使用
let _openw=null
if (_openw) { return } // 防止快速點擊
_openw = createWebview('http://xxxx.cn:9000/#/scan', 'scan', '掃碼')
_openw.addEventListener('loaded', function () {//頁面加載完成后才顯示
_openw && _openw.show('zoom-fade-out', null, function () {
_openw = null//避免快速點擊打開多個頁面
})
}, false)
_openw.addEventListener('hide', function () {
_openw = null
}, false)
_openw.addEventListener('close', function () {//頁面關閉后可再次打開
_openw = null
首頁檢測到新面關閉后 刷新首頁
that.componentDidMount()
}, false)