近期公司须要针对分享流程举行优化,个中一点就是
前端H5检测是不是装置运用,来举行差别的推断(下载或直接跳转到app中)。道理很简朴:建立一个
iframe去翻开
uri。假如翻开app胜利网页进入背景,再切换返来时候会凌驾2.5s。
应用时候去检测。下面来看细致完成历程:
你能够会碰到的题目
- 什么是uri,猎取uri须要哪些协助?
- 安卓中运用切换到背景, 计时器仍会不停运转有什么处理方法?
- 微信中不支撑第三方uri,下载运用。怎样处理来完成跳转到本身app。
- 补充 假如uri跳转的是webview页的话document并没有被隐蔽,推断会能够失效
都会在文中找到答案。
uri猎取
这里的uri,指得就是经由过程 Url scheme 来完成的H5与安卓、苹果运用之间的跳转链接。
我们须要找到客户端的同事,来猎取以下花样的链接。
xx://'跳转页面'/'照顾参数'
这里给人人简朴诠释下url scheme。
url 就是我们寻常明白的链接。
scheme 是指url链接中的最初位置,就是上边链接中 ‘xx’的位置。
细致引见能够看这里:
运用url scheme详解
用这个链接我们能够跳转到 运用中的某个页面,并能够照顾肯定的参数。这个是我们完成这个功用的条件哟。
细致完成
第一步:经由过程iframe翻开App
Android平台则各个app厂商差别很大,比方Chrome从25及今后就不再支撑经由过程js触发(非用户点击),所以这里运用iframe src地点等来触发scheme。
//在iframe 中翻开APP
var ifr = document.createElement('iframe');
ifr.src = openUrl;
ifr.style.display = 'none';
第二步: 推断是不是装置某运用
道理:若经由过程url scheme 翻开app胜利,那末当前h5会进入背景,经由过程计时器会有显著耽误。应用时候来推断。
//搜检app是不是翻开
function checkOpen(cb){
var _clickTime = +(new Date());
function check(elsTime) {
if ( elsTime > 3000 || document.hidden || document.webkitHidden) {
cb(1);
} else {
cb(0);
}
}
//启动距离20ms运转的定时器,并检测累计斲丧时候是不是凌驾3000ms,凌驾则完毕
var _count = 0, intHandle;
intHandle = setInterval(function(){
_count++;
var elsTime = +(new Date()) - _clickTime;
if (_count>=100 || elsTime > 3000 ) {
clearInterval(intHandle);
check(elsTime);
}
}, 20);
}
注重:
- 因为安卓手机,页面进入背景,定时器setTimeout仍会不停运转,所以这里运用setInterval,较小距离时候反复屡次。来依据累计时候推断。
- cb为回调函数,依据返回0 or 1来推断是不是装置。
- document.hidden对大于4.4webview支撑很好,为页面可见性api。
第三步:微信中完成翻开or下载运用结果
这里运用的是
运用宝微链接完成。
if (callback) {
//客户端检测微信直接跳运用宝链接
var browser = BrowserInfo();
//运用微链接
var encodeUri = encodeURIComponent('你的uri');
if (browser.isWeixin) {
window.location.href = '你的微链url&android_schema='+encodeUri;
}else{
checkOpen(function(opened){
callback && callback(opened);
});
}
}
注重点:
- 微链接是运用宝供应的,能够在背景猎取。
- 运用微链接必需做encodeURIComponent转义。
- 链接地点在微链接后拼接一个android_schema参数加你的uri。
完全函数
export const openApp = function(openUrl, callback) {
//搜检app是不是翻开
function checkOpen(cb){
var _clickTime = +(new Date());
function check(elsTime) {
if ( elsTime > 3000 || document.hidden || document.webkitHidden) {
cb(1);
} else {
cb(0);
}
}
//启动距离20ms运转的定时器,并检测累计斲丧时候是不是凌驾3000ms,凌驾则完毕
var _count = 0, intHandle;
intHandle = setInterval(function(){
_count++;
var elsTime = +(new Date()) - _clickTime;
if (_count>=100 || elsTime > 3000 ) {
clearInterval(intHandle);
check(elsTime);
}
}, 20);
}
//在iframe 中翻开APP
var ifr = document.createElement('iframe');
ifr.src = openUrl;
ifr.style.display = 'none';
if (callback) {
//客户端检测微信直接跳运用宝链接
var browser = BrowserInfo();
//运用微链接
var encodeUri = encodeURIComponent(openUrl);
if (browser.isWeixin) {
window.location.href = '你的微链url&android_schema='+encodeUri;
}else{
checkOpen(function(opened){
callback && callback(opened);
});
}
}
document.body.appendChild(ifr);
setTimeout(function() {
document.body.removeChild(ifr);
}, 2000);
}
其他
函数中挪用的BrowserInfo是一个简朴的客户端检测。细致以下:
/**
* 客户端检测
*/
export const BrowserInfo = function() {
var json = {
userAgent: navigator.userAgent.toLowerCase(),
isAndroid: Boolean(navigator.userAgent.match(/android/ig)),
isIphone: Boolean(navigator.userAgent.match(/iphone|ipod/ig)),
isIpad: Boolean(navigator.userAgent.match(/ipad/ig)),
isWeixin: Boolean(navigator.userAgent.match(/MicroMessenger/ig)),
}
return json;
}
回调函数的运用
页面中能够经由过程传递回调函数,来猎取返回值;并经由过程是不是传这个参数来做进入页面检测。