1,请详解移动端点透,为什么会发生点透?描述发生的场景及解决方案,(越多越好)
点透场景
层A 覆盖在层B上面,常见的有对话框等,层A用 touchstart 或者tap(zepto)事件点击进行隐藏或者移开,由于click晚于touchstart,超过300ms,当层A隐藏后,click到的是下面的层B,此时层B的click事件会触发,或者其上的a链接会跳转,input,select会吊起键盘。
zepto的tap事件原理
zepto的 tap 事件是通过 touchstart , touchend (android 4.0.x不支持touchend,通过touchmove 设置定时器触发touched)模拟出来的,事件是绑定在document上,大体思路是在touchstart的时候向对象附加点击的x,y;(其中还包含很多细节,比如设置最后点击时间,设置长按定时器等);touchmove的过程动态的计算手势在view上的偏移点,最后touchend 根据偏移点确定是否是点击,如果是点击动态的构建一个event然后根据设置的状态获取是单机、双击。
非zepto的tap事件未必会出现点透问题。
点透解决方案
来得很直接github上有个fastclick可以完美解决 https://github.com/ftlabs/fastclick
引入fastclick.js,因为fastclick源码不依赖其他库所以你可以在原生的js前直接加上
.touchFix{visibility: hidden;width: 100%;height: 100%;position: absolute;left: 0px;top: 0px;z-index: 9999;}
2> touchstart换成touchend,因为触发touchend需要200ms所以可以把触发时间这个原理问题解决掉
$("#cbFinish").on("touchend",function (e) {
e.preventDefault();
});
3> zepto最新版已经修复了这个问题,或者使用fastclick、hammer等通用库
4> 直接用click,不考虑延迟
5> 下层避开click事件,如a链接改为span等标签,使用js跳转页面
2,移动端为什么会有一像素问题?如何解决?
为什么会有一像素问题?
因为在移动端,由于屏幕分辨率的不同,现在分为一倍屏、二倍屏、三倍屏。在不同的分辨率上,有可能一像素被渲然成二个像素点或者三个像素点,所以在实际写代码的时候,我们写的 border: 1px solid #000; 可能实际被渲然为 2px/3px;
先使用伪类元素实现边框效果,然后通过媒体查询来操控transform: scale来适配不同分辨率
.border-bottom{position: relative;}.border-bottom::after{content:" ";position: absolute;left:0;bottom:0;width:100%;height:1px;background-color:#e4e4e4;-webkit-transform-origin: left bottom;transform-origin: left bottom;}/* 2倍屏 */@mediaonly screen and (-webkit-min-device-pixel-ratio:2.0) {.border-bottom::after{-webkit-transform:scaleY(0.5);transform:scaleY(0.5); }}/* 3倍屏 */@mediaonly screen and (-webkit-min-device-pixel-ratio:3.0) {.border-bottom::after{-webkit-transform:scaleY(0.33);transform:scaleY(0.33); }}
使用border-image来代替border
.border-image-1px{border-width:1px0px;-webkit-border-image:url("border.png")20stretch;border-image:url("border.png")20stretch;}
使用viewport +rem
设置meta标签
并在js中通过判断当前是一倍屏还是二倍屏、三倍屏,来动态的设置meta标签的内容
functionrem(){document.documentElement.style.fontSize =document.documentElement.clientWidth /7.5+'px';letviewport =document.querySelector("#WebViewport")if(window.devicePixelRatio ==1) { viewport.setAttribute('content','width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no') }if(window.devicePixelRatio ==2) { viewport.setAttribute('content','width=device-width, initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no') }if(window.devicePixelRatio ==3) { viewport.setAttribute('content','width=device-width, initial-scale=0.333333333, maximum-scale=0.333333333, minimum-scale=0.333333333, user-scalable=no') } }rem()window.onresize = rem;// 文章由 郝晨光 整理,未经同意禁止转载
border.css