發發牢騷
移動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 -->