请详解移动端点透,为什么会发生点透?描述发生的场景及解决方案
什么是点击穿透?
假如页面上有两个元素A和B。B元素在A元素之上。我们在B元素的touchstart事件上注册了一个回调函数,该回调函数的作用是隐藏B元素。我们发现,当我们点击B元素,B元素被隐藏了,随后,A元素触发了click事件。
这是因为在移动端浏览器,事件执行的顺序是touchstart > touchend > click。而click事件有300ms的延迟,当touchstart事件把B元素隐藏之后,隔了300ms,浏览器触发了click事件,但是此时B元素不见了,所以该事件被派发到了A元素身上。如果A元素是一个链接,那此时页面就会意外地跳转,input,select会吊起键盘。
点透的解决方法:
方案一:来得很直接github上有个fastclick可以完美解决
引入fastclick.js,因为fastclick源码不依赖其他库所以你可以在原生的js前直接加上
window.addEventListener( "load", function() {
FastClick.attach( document.body );
}, false );
或者有zepto或者jqm的js里面加上
$(function() {
FastClick.attach(document.body);
});
当然require的话就这样:
var FastClick = require('fastclick');
FastClick.attach(document.body, options);
方案二:用touchend代替tap事件并阻止掉touchend的默认行为preventDefault()
$("#cbFinish").on("touchend", function (event) {
//很多处理比如隐藏什么的 event.preventDefault();
});
方案三:延迟一定的时间(300ms+)来处理事件
$("#cbFinish").on("tap", function (event) {
setTimeout(function(){
//很多处理比如隐藏什么的 },320);
});
移动端为什么会有一像素问题?如何解决?
由于分辨率 DPI 的差异,高清手机屏上的 1px 实际上是由 2×2 个像素点来渲染,有的屏幕甚至用到了 3×3 个像素点
所以在实际的代码实现中,设置1px的边框,会渲染成2px.
一、使用transform: scale
先使用伪类 :after 或者 :before 创建 1px 的边框,然后通过 media 适配不同的设备像素比,然后调整缩放比例,从而实现一像素边框
.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倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
/* 3倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.33);
transform: scaleY(0.33);
}
}
或者,直接rem设置。