zepto之tap事件点透问题分析及解决方案

点透现象出现的场景:前端

  当A/B两个层上下z轴重叠,上层的A点击后消失或移开(这一点很重要),而且B元素自己有默认click事件(如a标签)或绑定了click事件。在这种状况下,点击A/B重叠的部分,就会出现点透的现象。git

点透现象出现的缘由:github

  zepto的tap事件是经过兼听绑定在document上的touch事件来完成tap事件的模拟的,而且tap事件是冒泡到document上触发的!!!浏览器

  在移动端不使用click而用touch事件代替触摸是由于click事件有着明显的延迟,具体touchstart与click的区别以下:动画

  touchstart:在这个DOM(或冒泡到这个DOM)上手指触摸开始即能当即触发;ui

  click:在这个DOM(或冒泡到这个DOM)上手指触摸开始,且手指不曾在屏幕上移动(某些<a href=”http://www.jd.com”>浏览器</a>容许移动一个很是小的位移值),且在这个DOM上手指离开屏幕,且触摸和离开屏幕之间的间隔时间较短(某些浏览器不检测间隔时间,也会触发click)才能触发事件

  也就是说,在移动端事件的触发时间按由早到晚排列为:touchstart 早于 touchend 早于 click。亦即click的触发是有延迟的,这个时间大概在300ms左右。zepto

  因为咱们在touchstart阶段就已经隐藏了罩层A,当click被触发时候,可以被点击的元素则是其下的B元素,根据click事件的触发规则:只有在被触发时,当前有click事件的元素显示,且在面朝用户的最前端时,才触发click事件。因为B绑定了click事件(或者B自己默认存在click事件),因此B的click事件被触发,产生了点透的状况。源码

点透现象解决方案:it

解决方案一:来得很直接github上有个fastclick能够完美解决https://github.com/ftlabs/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);

解决方案二:

对于B元素自己存在默认click事件的状况,应及用touchend代替tap事件并阻止掉时A元素touchend的默认行为preventDefault(),从而阻止click事件的产生。

 $("#aa").on("touchend", function (event) {

     //不少处理好比隐藏什么的

     event.preventDefault();

 });

对于B元素自己没有默认click事件的状况(无a标签等),应统一使用touch事件,统一代码风格,而且因为click事件在移动端的延迟要大不少,不利于用户体验,因此关于触摸事件应尽可能使用touch相关事件。

解决方案三:延迟必定的时间(300ms+)来处理事件

 $("#aa").on("tap", function (event) {

     setTimeout(function(){

     //不少处理好比隐藏什么的

     },320);

 });   

这种方法其实很好,能够和fadeInIn/fadeOut等动画结合使用,能够作出过分效果

解决方案四: 理论上上面的方法能够完美的解决tap的点透问题,若是真的倔强到不行,改用click。特别是对于遮盖浮层,因为遮盖浮层的点击即便有小延迟也是没有关系的,反而会有疑似更好的用户体验,因此这种状况,能够针对遮盖浮层本身采用click事件,这样就不会出现点透问题。

相关文章
相关标签/搜索