H5 頁面喚起APP或跳轉到下載APP的某個鏈接地址。總結如下:
在 IOS 中, 系統版本在 8 以下時,可以監聽頁面的 pagehide / visibilitychange 事件。 系統版本大於 8 以后,可以使用 universal Link 或 URL scheme 進行跳轉。
// IOS 的喚起
function
vForIOS(urlScheme, storeURL, fallback, universalLink) {
var
tid = deferFallback(TIMEOUT_IOS, storeURL, fallback);
if
(parseInt(os.version, 10) < 8) {
bindPagehideEvent(tid);
}
else
{
bindVisibilityChangeEvent(tid);
}
if
(parseInt(os.version, 10) > 8 && os.name ==
'iOS'
) {
// 通過universalLink
if
(universalLink === undefined) {
universalLink = urlScheme;
}
else
{
clearTimeout(tid);
}
vLocation(universalLink);
}
else
{
vIframe(urlScheme);
}
}
|
在安卓中, 安卓版本 4.4.4 以上機型的安卓自帶瀏覽器、chrome 瀏覽器,需要通過 intent 跳轉 【詳情請見 https://developer.chrome.com/multidevice/android/intents】,其他瀏覽器大多數可通過 url scheme 喚起。但由於喚起APP后瀏覽器並無回調事件,我們很難判斷是否已成功拉起APP,比較通用的解決辦法是判斷計時器是否變慢,若APP啟動瀏覽器最小化入后台將會導致計時器變慢,即為實際事件間隔大於理想時間間隔。若未變慢則判斷為未成功拉起APP,則跳轉至下載地址。此判斷代碼如下:
function
deferFallback(timeout, storeURL, fallback) {
var
clickedAt =
new
Date().getTime();
return
setTimeout(
function
() {
var
now =
new
Date().getTime();
if
(isPageVisible() && now - clickedAt < timeout + INTERVAL) {
fallback(storeURL);
}
}, timeout);
}
|
安卓系統中,不同瀏覽器對喚起APP有嚴重的兼容性問題,主要處理方案有以下幾種:
- 通過改變 window.location.href
- 通過創建 iframe 並為其 src 賦值
- 通過 intent
- 通過制造不可見 a 鏈接,並觸發點擊時間
// 打開頁面的方式可能
// 1. 通過改變location
function
vLocation(urlScheme) {
window.location.href = urlScheme;
}
// 2. 通過ifreame
function
vIframe(urlScheme) {
setTimeout(
function
() {
var
iframe = createHiddenIframe(
'appLauncher'
);
iframe.src = urlScheme;
}, 100);
}
// 3. 通過intent
function
vIntent(launchURI) {
if
(browser.name ==
'Chrome'
) {
move();
}
else
{
setTimeout(move, 100);
}
function
move() {
// window.top.location.href = launchURI;
window.location.href = launchURI
}
}
// 3. 通過添加出發alink
function
vAlink(launchURI) {
var
aLink = document.createElement(
"a"
);
aLink.setAttribute(
"href"
, launchURI);
aLink.style.display =
"none"
;
document.body.appendChild(aLink);
var
event = document.createEvent(
"HTMLEvents"
);
event.initEvent(
"click"
, !1, !1);
aLink.dispatchEvent(event)
}
// IOS 中的 可見性事件
function
bindPagehideEvent(tid) {
window.addEventListener(
'pagehide'
,
function
clear() {
if
(isPageVisible()) {
clearTimeout(tid);
window.removeEventListener(
'pagehide'
, clear);
}
});
}
function
bindVisibilityChangeEvent(tid) {
document.addEventListener(
'visibilitychange'
,
function
clear() {
if
(isPageVisible()) {
clearTimeout(tid);
document.removeEventListener(
'visibilitychange'
, clear);
}
});
}
function
isPageVisible() {
var
attrNames = [
'hidden'
,
'webkitHidden'
];
for
(
var
i = 0, len = attrNames.length; i < len; i++) {
if
(
typeof
document[attrNames[i]] !==
'undefined'
) {
return
!document[attrNames[i]];
}
}
return
true
;
}
|
已知的瀏覽器兼容問題:
- 上述 chrome 和 Android Browser 可以使用 intent 的方式拉起 app
- QQ 瀏覽器 無法正確判斷計時器是否變慢
- 微信瀏覽器 和 百度瀏覽器 無法喚起 app 除非加入其白名單
- 安卓4.4.4以前的 UC瀏覽器無法正確識別為 【安卓系統】需要單獨設置判斷條件
另: 研究京東喚起APP的代碼時,其對百度瀏覽器做了如下操作,但我們對此的嘗試並為成功,如下為其代碼, 希望對后續研究此項的同學有幫助 :
function
ai(aA) {
var
aD = ay(aA,
true
);
var
aB = aA.universalLinksUrl +
"/ul/ul.action?"
+ aD;
if
(navigator.userAgent.indexOf(
"baidubrowser"
) >= 0) {
window.location.href = aB
}
else
{
var
az = document.createElement(
"a"
);
az.setAttribute(
"href"
, aB);
az.style.display =
"none"
;
document.body.appendChild(az);
var
aC = document.createEvent(
"HTMLEvents"
);
aC.initEvent(
"click"
, !1, !1);
az.dispatchEvent(aC)
}
}
|