发发牢骚
移动web端里摸爬滚打这么久踩了不少坑,有一定移动web端经验的同学一定被click困扰过。我也不列外。一路走来被虐的不行,fastclick、touchend、iscroll什么的都用过,各有优劣,都不能一步到位。最后实在是被逼无奈,翻阅了不少资料,自定义了一个tap。
效果预览
废话不多说先上效果 移动端预览
一探真假
真的只有10行
插件是基于jQuery的,上代码。
//自定义tap $(document).on("touchstart", function(e) { if(!$(e.target).hasClass("disable")) $(e.target).data("isMoved", 0); }); $(document).on("touchmove", function(e) { if(!$(e.target).hasClass("disable")) $(e.target).data("isMoved", 1); }); $(document).on("touchend", function(e) { if(!$(e.target).hasClass("disable") && $(e.target).data("isMoved") == 0) $(e.target).trigger("tap"); });
既然说是10行代码搞定,那么就一定是10行。
实现原理
基于touchstart、touchmove、touchend这三个事件,通过事件委托的方式来实现tap事件。
e.target是事件源的触发节点,$(e.target)是该节点的jQuery封装对象。
第一步:监听touchstart事件,事件触发后通过jQuery的data方法设置该对象的isMoved状态为0。
第二步:监听touchmove事件,事件触发后通过jQuery的data方法设置该对象的isMoved状态为1。
第三步:监听touchend事件,事件触发后判断该对象是否touchend过,没有则触发tap事件。
使用方法
把上面的10行代码放在jQuery或者zepto的最后面,用法和一般事件一样
其他
目前还没有做PC端的兼容,移动web端的机型测试做的不够多,后续会慢慢补上。如果在使用中遇到了什么问题可以留言。
<!doctype html> <html lang="zh-cn"> <head> <meta name="viewport" content="initial-scale=1, user-scalable=0, minimal-ui" charset="UTF-8"> <title>tap</title> <script id="jquery_180" type="text/javascript" class="library" src="/js/sandbox/jquery/jquery-1.8.0.min.js"></script> </head> <body> <div class="layer1"> <div class="layer2"> <div class="layer3"> </div> </div> </div> <div class="window"> </div> </body> </html> <style>.layer1 { width: 100%; height: 200px; background-color: #888; } .layer2 { width: 67%; height: 67%; background-color: #aaa; } .layer3 { width: 67%; height: 67%; background-color: #ccc; } .window { position: fixed; top: 50px; left: 10%; width: 80%; height: 200px; background-color: #099; }</style> <script>$(function () { //自定义tap $(document).on("touchstart", function(e) { var $target = $(e.target); if(!$target.hasClass("disable")) $target.data("isMoved", 0); }); $(document).on("touchmove", function(e) { var $target = $(e.target); if(!$target.hasClass("disable")) $target.data("isMoved", 1); }); $(document).on("touchend", function(e) { var $target = $(e.target); if(!$target.hasClass("disable") && $target.data("isMoved") == 0) $target.trigger("tap"); }); $(".layer1").on("tap", function(e) { alert("layer1"); }); $(".layer2").on("tap", function(e) { alert("layer2"); e.stopPropagation(); }); $(".layer3").on("tap", function(e) { alert("layer3"); e.stopPropagation(); }); $(".window").on("tap", function(e) { alert("window"); }); });</script> <!-- Generated by RunJS (Thu Sep 01 11:54:18 CST 2016) 0ms -->