移动端兼容性问题解决方案
1. IOS移动端click事件300ms的延迟响应
移动设备上的web网页是有300ms延迟的,往往会造成按钮点击延迟甚至是点击失效。这是由于区分双击事件和双击屏幕缩放的历史原因造成的,
2007年苹果发布首款iPhone上IOS系统搭载的safari,为了将适用于PC端上大屏幕的网页能比较好的展示在手机端上,使用了双击缩放(double tap to zoom)的方案,比如你在手机上用浏览器打开一个PC上的网页,你可能在看到页面内容。虽然可以撑满整个屏幕,但是字体、图片都很小看不清,此时可以快速双击屏幕上的某一部分,你就能看清该部分放大后的内容,再次双击后能回到原始状态。
双击缩放是指用手指在屏幕上快速点击两次,IOS 自带的 Safari 浏览器会将网页缩放至原始比例。
原因就出在浏览器需要如何判断快速点击上,当用户在屏幕上单击某一个元素时候,例如跳转链接<a href="#"></a>,此处浏览器会先捕获该次单击,但浏览器不能决定用户是单纯要点击链接还是要双击该部分区域进行缩放操作,所以,捕获第一次单击后,浏览器会先Hold一段时间,如果在这段时间里用户未进行下一次点击,则浏览器会做单击跳转链接的处理,如果在这段时间里用户进行了第二次单击操作,则浏览器会禁止跳转,转而进行对该部分区域页面的缩放操作。那么这个时间区间t有多少呢?在IOS safari下,大概为300毫秒。这就是300ms延迟的由来。造成的后果是用户纯粹单击页面,页面需要过一段时间才响应,给用户慢体验感觉,对于web开发者来说是,页面JS捕获click事件的回调函数处理,需要300ms后才生效,也就间接导致影响其它业务逻辑的处理。
解决方案:
- fastclick可以解决在手机上点击事件300ms的延迟
- zepto的touch模块,tap事件也是为了解决click的延迟问题
- 触摸事件的响应顺序为 touchstart --> touchmove --> touchend --> click,也可以通过绑定ontouchstart事件,加快对事件的响应,解决300ms延迟问题
这个300ms的延时会引发另外一个问题---点击穿透
点击穿透的原因:
1.浏览器有300ms的延时为了区别是double click还是缩放
2.移动端事件的响应顺序 touchstart -> touchmove -> touchend -> tap -> click
在300ms时间范围内,上层元素隐藏了或移开了,下层相同位置的元素触发了click事件(普通元素是click事件回调函数效果,input,select是focus事件,超链接是页面跳转)
解决方案是:
方案一: 下层元素本身无click事件,没有input select a标签,统一使用touch事件
方案二:下层元素本身无click事件,在上方元素的touchend事件回调函数中,阻止后续触发默认事件 e.preventDefault();
1 $("#cbFinish").on("touchend", function (event) { 2 //很多处理比如隐藏什么的 3 event.preventDefault(); 4 });
方案三:延迟一定的时间(300ms+)来处理事件
1 $("#cbFinish").on("tap", function (event) { 2 setTimeout(function(){ 3 //很多处理比如隐藏什么的 4 },320); 5 });
方案四:在上层显示以后加入对应的class名控制,截断显示层下方可获取焦点元素的事件获取
2.一些情况下对非可点击元素如(label,span)监听Click事件,IOS下不会触发,CSS增加cursor:pointer就搞定了。
3. H5底部输入框被键盘遮挡问题
h5页面有个很蛋疼的问题就是,当输入框在最底部,点击软键盘后输入框会被遮挡。可采用如下方式解决
方案一:
// 让dom元素出现在可见视图的顶部或底部,只要在input的点击事件,或者获取焦点的事件中,加入这个api就好了 document.querySelector('#inputId').scrollIntoView();
方案二:
//浏览器当前的高度 var oHeight = $(document).height(); $(window).resize(function(){ if($(document).height() < oHeight){ $("#footer").css("position","static"); }else{ // 高度超出初始状态,设置绝对定位,可以让底部输入框显示在可见区域 $("#footer").css("position","absolute"); } });
4.不让 Android 手机识别邮箱
<meta content="email=no" name="format-detection" />
5.禁止 iOS 识别长串数字为电话
<meta content="telephone=no" name="format-detection" />
6.禁止 iOS 弹出默认的各种操作窗口, 在iOS上,当你触摸并按住触摸的目标,比如一个链接,Safari浏览器将显示链接有关的系统默认菜单。这个属性可以让你禁用系统默认菜单。适用于链接元素比如新窗口打开,img元素比如保存图像等等
-webkit-touch-callout:none
7.消除 transition 闪屏
-webkit-transform-style: preserve-3d; /*设置内嵌的元素在 3D 空间如何呈现:保留 3D*/ -webkit-backface-visibility: hidden; /*(设置进行转换的元素的背面在面对用户时是否可见:隐藏)*/
8.iOS 系统中文输入法输入英文时,字母之间可能会出现一个六分之一空格
// 可以通过正则去掉 this.value = this.value.replace(/\u2006/g, '');
9.禁止ios和android用户选中文字
-webkit-user-select:none
10.在ios和andriod中,audio元素和video元素在无法自动播放
应对方案:触屏即播
$('html').one('touchstart',function(){ audio.play() })
11.ios下取消input在输入的时候英文首字母的默认大写
<input autocapitalize="off" autocorrect="off" />
12.android下取消输入语音按钮
input::-webkit-input-speech-button {display: none}
13 CSS动画页面闪白,动画卡顿
解决方法:
1.尽可能地使用合成属性transform和opacity来设计CSS3动画,不使用position的left和top来定位
2.开启硬件加速
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
14.阻止旋转屏幕时自动调整字体大小
html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 { -webkit-text-size-adjust:none; }
15. Input 的placeholder会出现文本位置偏上的情况
input 的placeholder会出现文本位置偏上的情况:PC端设置line-height等于height能够对齐,而移动端仍然是偏上,解决是设置line-height:normal
16 往返缓存问题
点击浏览器的回退,有时候不会自动执行js,特别是在mobilesafari中。这与往返缓存(bfcache)有关系。
// 解决方法 : window.onunload = function(){};
17 在移动端修改难看的点击的高亮效果,iOS和安卓下都有效:
* {-webkit-tap-highlight-color:rgba(0,0,0,0);}
不过这个方法在现在的安卓浏览器下,只能去掉那个橙色的背景色,点击产生的高亮边框还是没有去掉,有待解决!
有一个CSS3的属性,加上后,所关联的元素的事件监听都会失效,等于让元素变得“看得见,点不着”。IE到11才开始支持,其他浏览器的当前版本基本都支持。详细介绍见这里,可以解决点击难看的高亮效果。
pointer-events: none;
18. user-select:none;造成iPhone5上输入框的光标不显示,输入时如果不显示光标,那将无法看到输入位置。因此这个属性不能用在input元素上
19. IOS手机,在react框架中,输入框输入内容添加去除空白逻辑,会造成中文拼音输入法,未及时选择中文,输入框出现许多拼音字母。还有maxLength属性,输入时不限制长度,输入结束才会自动截短。
<input maxLength={20} value={taskName} onChange={(e) => this.setState({ taskName: e.target.value.replace(/\s*/g, '') })} placeholder="请输入,20个字符以内" />
20. 华为手机,输入文字弹出键盘,键盘收缩回去之后。页面的高度不会复原成真正的100vh,而仍停留在有键盘弹出时的高度,如果页面设置了全屏背景,就会出现页面有一部分没有背景。解决方法是监听window.onresize事件,手动恢复页面高度
21. 解决iphone下选中input页面自动放大的问题,viewport的user-scalable要设置成no
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,viewport-fit=cover" />