1. 需求
前段時間開發專案,遇到了一個需求,簡單來說,就是我們H5的頁面有一個“在App
中開啟”的按鈕,使用者點選後,如果使用者已經安裝app
,則直接開啟app
,如果使用者沒有安裝app
,那就跳轉到下載app
的頁面
首先,在我的認知中,H5應該是沒有能力檢測到某一款app是否有安裝的(如果有小夥伴知道如何檢測,歡迎評論區告訴我,感謝!),所以我們需要一些技巧來完成判斷app是否安裝這一過程。
之後的步驟以安卓手機為例子介紹,目前ios9
版本之後的系統不需要我們H5
做這些判斷app
是否安裝的流程(ios9之後
可以通過提供一個通用連結(Universal link)
,做到沒有安裝app提示開啟蘋果應用商城,安裝了app則直接跳轉開啟)
2. 關於scheme協議
scheme協議是一種頁面內跳轉協議,我們可以通過定製scheme協議,跳轉到app中的想要跳轉的各個頁面。scheme
協議是通過url
的形式進行跳轉的,所以我們H5
也可以通過這個url
去跳轉到app
內指定頁面,這就是H5開啟app
的原理。
scheme的url格式類似:[scheme]://[host]/[path]?[query]
3. H5實現在App中開啟的兩種方法
3.1 單純使用定時器判斷
這種的方法的思路是,首先把我們要跳轉的地址設定為與原生App
同學一起定義好的scheme
的url
,之後,設定一個定時器,定時器裡執行的邏輯是跳轉到下載app
頁面,這樣,如果使用者手機沒有安裝app
,就會在一段時間後跳轉到下載頁面。
核心程式碼如下:(可以使用iframe
完成跳轉,但需要考慮iframe
是否在ios
等裝置中被允許)
const schemeUrl = 'xxx'
const downloadUrl = 'XXX'
const wait = 500
try {
location = schemeUrl
setTimeout(() => {
location = downloadUrl
}, wait)
} catch (e) {
console.error(e)
}
複製程式碼
存在的問題
上述實現方案的問題是,即使成功跳轉到App
,原先的H5
頁面也會在定時時間後,跳轉到下載頁面,這樣體驗很不好
3.2 使用window的hidden屬性判斷
這個方法的思路是,如果成功喚起了app
,我們的H5頁面被置於後臺,window.hidden
屬性會變為true
,可以通過這個屬性變化來判斷app
有沒有開啟,沒開啟就跳轉到下載頁面,當然這裡也用到定時器
核心程式碼如下:
function checkOutApp() {
const schemeUrl = 'xxx'
const downloadUrl = 'XXX'
const wait = 1000
// 是否進入後臺
const hidden = false
location = schemeUrl
// 如果一定時間內,頁面沒有隱藏,則跳轉到下載頁
setTimeout(() => {
if (!hidden) {
location = downloadUrl
}
}, wait)
// 頁面可見性變化事件
document.addEventListener("visibilitychange", function(){
if (document.hidden) {
hidden = true
}
});
}
複製程式碼
存在的問題
目前一些安卓瀏覽器,在app存在時,會首先跳出一個確認框,詢問使用者是否開啟app,只有使用者同意時,才會跳轉app,如果使用者始終沒有點選確認,最後還是會跳到下載頁面,體驗不好
4. 一些思考
鑑於上面說到的一些問題,個人覺得可以在互動中增加一個“去下載頁面”的互動,如果使用者沒有安裝app,一定時間後,首先提示使用者“是否沒有安裝app,點選去下載”類似的按鈕,使用者點選跳轉到下載頁面,這樣會不會更好呢。