又到周末了,我们一起来研究【浏览器如何检测是否安装app】吧
前言
扯淡
这个月比较倒霉,我送了女朋友一台笔记本电脑作为生日礼物,结果15天一过电脑就坏了,悲剧的我还把电脑盒子给扔了!淘宝不给换更不给退
于是被女朋友臭骂了一过星期后,今天本来在公司有任务的,但是去修了个电脑(换主板啊......),一蹉跎就快五点了,现在反正干劲也不行,就写篇博客吧
需求
上周五的时候,确切说是周四晚上,老板终于又递上了一个神奇的需求
浏览器检测手机是否安装app
尼玛,反正在我看来,这个需求够奇葩的,当时我还一致认为不能完成,但是最后也居然想出了(抄出了)一个办法,于是这里拿出来与各位分享下
在此之前,我们继续聊下上次遇到的tap点透问题
tap“点透”再探索
http://www.cnblogs.com/yexiaochai/p/3377900.html
http://www.cnblogs.com/yexiaochai/p/3391015.html
看过上面两篇博客的的朋友应该知道我们为什么要使用tap事件替换click事件,然后大概知道tap会带来哪些问题,以及我是如何解决这些问题的
虽然完整解决方案因为公司财产问题未拿出来,但是基本思路是有了,其核心就是蒙版遮盖!
话说还头,这个蒙版其实还是不太能让人接受,这不我又请教了我一个同事,我们同事提出了一个属性:
pointer-events属性值详解
- auto——效果和没有定义pointer-events属性相同,鼠标不会穿透当前层。在SVG中,该值和visiblePainted的效果相同。
- none——元素不再是鼠标事件的目标,鼠标不再监听当前层而去监听下面的层中的元素。但是如果它的子元素设置了pointer-events为其它值,比如auto,鼠标还是会监听这个子元素的。
- 其它属性值为SVG专用,这里不再多介绍了。
这个属性,通过前端观察/和张鑫旭的博客再深入了解一番过后发现,这个家伙可以消除一个元素的鼠标事件呢!!!自然也包括touchstart了,于是老夫感兴趣了,便有了今天这个插曲
是否继承
我们首先来看看这个属性是否会被继承:
http://sandbox.runjs.cn/show/teegz43u
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta content="telephone=no" name="format-detection" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<style>
div { display: block; border: 1px solid black; margin: 10px; padding: 10px; }
</style>
<script id="others_zepto_10rc1" type="text/javascript" class="library" src="/js/sandbox/other/zepto.min.js"></script> </head>
<body> <div id="p1">
p1
<div id="p1-1">
p1-1
<div id="p1-1-1">
p1-1-1
</div>
<div id="p1-1-2">
p1-1-2
</div>
</div>
</div> <div id="p2">
p2
<div id="p2-1">
2-1
<div id="p2-1-1">
p2-1-1
</div>
<div id="p2-1-2">
p2-1-2
</div>
</div>
</div> </body>
<script type="text/javascript">
$('div').click(function () {
alert($(this).attr('id')) })
</script>
</html>
首先,现在鼠标点击会有一个冒泡的过程,所以会一次弹出提示框,现在我们将下面的p2的style加上我们的pointer-events属性试试点击是否有效果
结果表明,设置了pointer-events: none; 后,该元素以及下面的元素的click事件全部没有了
甚至是我们的input框都不会获取焦点了!!!,所以这个家伙确实够厉害,但是不会取消事件冒泡
有了这个结论,我们上我们的重量级代码吧,这个代码请各位用手机测试
属性解决点透
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta content="telephone=no" name="format-detection" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<style>
#list { display: block; position: absolute; top: 100px; left: 10px; width: 200px; height: 100px; }
div { display: block; border: 1px solid black; height: 500px; width: 100%; }
#input { width: 80px; height: 200px; display: block; }
</style>
<script id="others_zepto_10rc1" type="text/javascript" class="library" src="/js/sandbox/other/zepto.min.js"></script>
</head>
<body>
<div id="list" style="background: gray;">
</div>
<div id="wrapper">
<div id="d">
<input type="text" id="input" />
</div>
</div>
</body>
<script type="text/javascript">
var list = $('#list');
var d = $('#d');
var input = $('#input');
input.tap(function (e) {
input.val(new Date().getTime());
});
list.tap(function (e) {
// $('input').css("pointer-events", "none");
list.hide();
setTimeout(function () {
list.show();
// $('input').css("pointer-events", "auto");
}, 1000);
});
d.tap(function () {
d.append($('<p>div tap</p>'));
}); </script>
</html>
http://sandbox.runjs.cn/show/wub3i7fr
这里各位请使用手机访问试试,现在这个网页有几个问题:
我点击灰色区域会将灰色区域隐藏,灰色区域消失,一秒后重现,于是可能发生两个问题:
① 某些浏览器中后面的div tap事件会触发
② input元素必定获得焦点
div事件有些时候我们可以通过阻止冒泡处理,但是input这个问题基本不可调和,因为其获得焦点弹出键盘十分恼火
元素我们是通过一个蒙版解决,先我们来看看是否可以给我们的容器wrapper加上一个css属性解决呢???
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta content="telephone=no" name="format-detection" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<style>
#list { display: block; position: absolute; top: 100px; left: 10px; width: 200px; height: 100px; }
div { display: block; border: 1px solid black; height: 500px; width: 100%; }
#input { width: 80px; height: 200px; display: block; }
</style>
<script id="others_zepto_10rc1" type="text/javascript" class="library" src="/js/sandbox/other/zepto.min.js"></script>
</head>
<body>
<div id="list" style="background: gray;">
</div>
<div id="wrapper">
<div id="d">
<input type="text" id="input" />
</div>
</div>
</body>
<script type="text/javascript">
var list = $('#list');
var d = $('#d');
var input = $('#input');
input.tap(function (e) {
input.val(new Date().getTime());
});
list.tap(function (e) {
$('#wrapper').css("pointer-events", "none");
list.hide();
setTimeout(function () {
$('#wrapper').css("pointer-events", "auto");
}, 350)
setTimeout(function () {
list.show();
}, 1000);
});
d.tap(function () {
d.append($('<p>div tap</p>'));
}); </script>
</html>
http://sandbox.runjs.cn/show/1wldtigt
可以看到,我们解决了点透的问题,所以有我有这些厉害的同事是很幸运的,有了这个方案,我们就可以在zepto中封装我们的代码了
在tap点击后为容器标签设置该属性,350ms后取消即可,这样可以最大程度的包装代码不会修改
但是这个方案不是没有问题:
最重要的是他依然有个时间阀值,经过我测试时350ms,意思是我使用tap事件后会有350ms的事件某些区域完全无法点击
那么容器所占区域小的话还可接受,如果所占区域大的话就是噩梦,因为用户的点击明显会出现阻力
然后,毕竟会点透的情况不是多数,所以此方案仍有缺陷,最后还是得动一些其它力气
后续
这次tap的研究先到这里,我们我们有机会再继续,所以回到我们今天的主题吧!!!
浏览器检测手机是否安装app
这个需求初次提出其实让人感觉很为难,至少我是很为难的,因为压根就找不到办法嘛,经过周四晚上的纠结,基本就放弃了
第二天也给老大说搞不定,老大基本也仍为搞不定,但是这个需求是最大的老大提出的,所以跟进力度很强,这不是,过了没多久就来了个vip(代表级别高......)
哥来了就寄出了法宝,先是一个国外的网站,然后就是我们传说中的淘宝了
PS:说实话,虽然电脑的事情与淘宝无关,但是老夫现在对淘宝还是比较怨念的!!!!
淘宝不愧是业内技术领先的技术团队,我们来看看他的网站:

其它不必关注,我们就看这个“立即打开”!!!各位知道手机上这个立即打开干了什么吗?
这个家伙不得了,如果按照了app 的话点击立即打开就会打开app,如果没有按照的话居然跳向了市场连接
在某些时候这个对等与他有一个a标签会根据需求而获得不同的值!!!
但是,我们知道打开app是安装了app才会打开的,不然就是个死链接,死链接必然打不开!于是带着好奇带着敬畏,我们打开了淘宝的js库
PS:淘宝压缩混淆后js确实很小,而且没有使用类库哦

各位看官直接找到这个目录吧,于是进去我们一步步跟进去:
① 点击点
虽然小生本领不行,但是读代码还是入门的,所以国内一旦出了什么心技术,基本很快就能普及,这就是国内的技术,不是做不出来,就是不知道做出了是什么样子
一旦你做出了,那么我也能做出了,并且做的更好,所以我们缺乏创新啊......

我们找到了入口,于是进入install方法
② install

这群代码一目了然,读到这里,其实可以很轻易的猜测实现方案了!

③ 猜测实现方案
于是我就开始猜测,猜测的结果就是:
如果安装app 的情况下,打开链接会让window失去焦点,于是清除了计时器
如果没有安装app计时器里面的代码会执行,所以跳向了app市场
当然,最后发现一个问题:手机上网页无法失去焦点,这只是我自己的判断(无法失去焦点),所以最后也放弃了这个猜测
④ 陷入僵局
于是思路再次陷入僵局,任务不能实现,但是将淘宝代码搞下来,也无法实现,最后就开始以各种漫无目的,垃圾的办法搞,终于不注意成功了一次!!!
无意义的成功是因为将定时器设置的很大......
⑤ 解决方案
最后发现了方案,安装app 的情况下,网页会进入后台打开app!!!
网页进入后台后会挂起js 的执行,但是这个期间有600-1000ms的时间js仍然会执行
淘宝执行的阀值是600,我们大概是900,所以一直在原地踏步了很久
这个网页进入后台却成了解决问题的关键,于是新鲜代码出来了:
var log = function (msg) {
$('body').before('<div class="log">' + msg + '</div>');
};
var timeout, t = 1000, hasApp = true;
setTimeout(function () {
if (hasApp) {
log('安装了app');
$('#dl_app').hide();
} else {
log('未安装app');
$('#dl_app').show();
log('开始强制下载');
forceDownload();
}
}, 2000)
function testApp() {
var t1 = Date.now();
var ifr = $('<iframe id="ifr"></iframe>')
ifr.attr('src', '您们app的协议');
$('body').append(ifr);
timeout = setTimeout(function () {
try_to_open_app(t1);
}, t);
}
function try_to_open_app(t1) {
var t2 = Date.now();
if (!t1 || t2 - t1 < t + 200) {
hasApp = false;
}
}
testApp();
将这段代码加入网站首页1-2秒后hasApp就会告诉我们是否安装了app,当然问题也很明显:
缺陷
① 经测试,如果未安装app的情况下,safari会给出一个alert类似的提示,老夫将它去不掉!!!
PS:如果各位知道怎么去掉,请赐教
② 进入H5站点,如果安装了app便会打开app,这个是无法避免的
除了上面两个较明显的缺陷,其它还好了......
结语
我们今天的学习暂时到此,也不知道对各位有没有用
又到周末了,我们一起来研究【浏览器如何检测是否安装app】吧的更多相关文章
- Emgu-WPF 激光雷达研究-移动物体检测
原文:Emgu-WPF 激光雷达研究-移动物体检测 接上篇: https://blog.csdn.net/u013224722/article/details/80738619 先pose出效果图,下 ...
- 5月第2周业务风控关注 | 央行:严禁未经授权认可的APP接入征信系统
本文由 网易云发布. 易盾业务风控周报每周呈报值得关注的安全技术和事件,包括但不限于内容安全.移动安全.业务安全和网络安全,帮助企业提高警惕,规避这些似小实大.影响业务健康发展的安全风险. 1.央行 ...
- MQTT协议学习研究 & Mosquitto简要教程(安装和使用)
若初次接触MQTT协议,可先理解以下概念: [MQTT协议特点]——相比于RESTful架构的物联网系统,MQTT协议借助消息推送功能,可以更好地实现远程控制. [MQTT协议角色]——在RESTfu ...
- 深入研究浏览器对HTML解析过程
HTML HTML解析 HTML解析是一个将字节转化为字符,字符解析为标记,标记生成节点,节点构建树的过程. 标记化算法 是词法分析过程,将输入内容解析成多个标记.HTML标记包括起始标记.结束标记. ...
- 浅谈Hybrid技术的设计与实现第二弹
前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hybrid技术的设计与实现第三弹——落地篇 接上文:浅谈Hybrid技术的设计与实现(阅读本文前,建议阅读这个先) ...
- 通过手机浏览器打开APP或者跳转到下载页面.md
目录 通过手机浏览器打开APP或者跳转到下载页面 添加 schemes 网页设置 参考链接 通过手机浏览器打开APP或者跳转到下载页面 以下仅展示最简单的例子及关键代码 由于硬件条件有限,仅测试了 A ...
- Android 如何通过浏览器打开App
首先给出参考资料http://my.oschina.net/liucundong/blog/354029?p=3#rpl_291191828 通过浏览器直接打开Android应用程序 Android ...
- 开始研究unreal4了
最后一个周末了,昨天去做了许多事,算是对最近的一些整理和了结吧.早上广州下雨了,9点起来吃了早餐之后又睡了1个小时.中午吃了泡面,幸福感max.晚上煎了菜脯蛋和肉卷,拖着拉着把<旋风十一人> ...
- 20155228 2016-2017-2 《Java程序设计》第1周学习总结
20155228 2016-2017-2 <Java程序设计>第1周学习总结 教材学习内容总结 这部分内容是以教材为基础,根据个人的理解来描述的,有的地方的理解和表述可能不规范甚至不正确, ...
随机推荐
- SpringMVC常用的注解
1. @Controller @Controller用于标识控制层主键,负责注册一个bean到spring上下文,bean的ID默认为首字母小写的类名称,用户也可以自定义. 例如: 方式一: @Co ...
- spring4mvc返回json(bean,list,map)
因为spring3和spring4的mvc在前端返回json所需要的jar包不一样,所以索性写一篇关于spring4mvc在前端返回json的博文. 首先,新建一个web项目,项目格式如图所示: co ...
- 轻量级前端MVVM框架avalon - ViewModel
废话说了大几篇,我们开始来点干货了~ ViewModel的内部机制 在MVVM中,数据是核心.而jQuery则以DOM为核心. 而DOM只是HTML在JS的世界的抽象,是一个很易变的东西.因此如果业务 ...
- Power BI官方视频(2) Power BI嵌入到应用中的3种方法
今天给大家介绍3种将Power BI嵌入到应用中的方法. 本文原文地址:Power BI官方视频(2) Power BI嵌入到应用中的3种方法 Power BI系列文章地址:微软Power BI技术文 ...
- Util应用程序框架公共操作类(一):数据类型转换公共操作类(介绍篇)
本系列文章将介绍一些对初学者有帮助的辅助类,这些辅助类本身并没有什么稀奇之处,如何能发现需要封装它们可能更加重要,所谓授之以鱼不如授之以渔,掌握封装公共操作类的技巧才是关键,我会详细说明创建这些类的动 ...
- Oracle手边常用命令及操作语句
Oracle手边常用命令及操作语句 作者:白宁超 时间:2016年3月4日11:24:08 摘要:日常使用oracle数据库过程中,常用脚本命令莫不是用户和密码.表空间.多表联合.执行语句等常规操作. ...
- centos7 mysql数据库安装和配置
一.系统环境 yum update升级以后的系统版本为 [root@yl-web yl]# cat /etc/redhat-release CentOS Linux release 7.1.1503 ...
- Mongodb 数据类型及Mongoose常用CURD
前言 看完了Node.js实战,其中在数据存储部分提到了Redis.Mongodb,我自己也根据书中的介绍写了几个简单的demo,在demo的过程首先遇到的问题就是数据类型和常见的CURD写法. mo ...
- 浅谈MITM攻击之信息窃取(解密315晚会报道的免费WIFI窃取个人信息)
前言 所谓的MITM攻击(即中间人攻击),简而言之就是第三者通过拦截正常的网络通信数据,并进行数据篡改和嗅探,而通信的双方毫无感知.这个很早就成为黑客常用的手段,一会聊的315晚会窃取个人信息只是 ...
- T4 模板自动生成带注释的实体类文件 - 只需要一个 SqlSugar.dll
生成实体就是这么简单,只要建一个T4文件和 文件夹里面放一个DLL. 使用T4模板教程 步骤1 创建T4模板 ,一定要自已新建,把T4代码复制进去,好多人因为用我现成的T4报错(原因不明) 点击添加文 ...