在上兩篇文章【10行代碼搞定移動web端自定義tap事件】【移動web端模擬hover效果】中分別對移動web端的自定義tap事件、模擬hover效果的原理進行了簡單的說明。這篇文章主要把二者結合在了一塊兒,解決了一些bug,使得總體效果更佳。web
以前的自定義tap沒有考慮到雙擊、長按等使用場景(感謝 @超級小麪包 的建議!),此次新增了langTap、doubleTap事件。模擬hover效果因爲是獨立於自定義tap的,效果有些小瑕疵,此次結合了tap,效果好了不少segmentfault
//tap定時器 var timer_tap; //langTap定時器 var timer_langTap; //自定義tap、doubleTap、langTap $(document).on("touchstart", function (e) { var $target = $(e.target); var tapData = $target.data("tapData"); //不處理含有disable class的對象 if ($target.hasClass("disable")) return; //狀態信息 tapData = tapData ? tapData : {}; tapData.state = "start"; tapData.isMoved = 0; tapData.preTouchStartTime = tapData.touchStartTime ? tapData.touchStartTime : null; tapData.touchStartTime = new Date().getTime(); //doubleTap if(tapData.preTouchStartTime && tapData.touchStartTime - tapData.preTouchStartTime < 250) { //doubleTap tapData.doubleTapTime = tapData.touchStartTime; //記錄信息 $target.data("tapData", tapData); //清除timer_tap clearTimeout(timer_tap); return; } //langTap timer_langTap = setTimeout(function() { var tapData = $target.data("tapData"); if(tapData.state != "start") return; $target.trigger("langTap"); if(tapData.$hover) tapData.$hover.removeClass("active"); }, 700); //尋找$hover對象 var $hover; if($target.hasClass("action-btn")) { $hover = $target; }else { $target.parents().each(function() { if($(this).hasClass("action-btn")) $hover = $hover ? $hover : $(this); }); } tapData.$hover = $hover; //記錄信息 $target.data("tapData", tapData); //點擊效果 if(!$hover) return; //延遲78ms setTimeout(function() { var tapData = $target.data("tapData"); //移動過 if(tapData.isMoved != 0) return; //添加點擊效果 tapData.$hover.addClass("active"); }, 78); }); $(document).on("touchmove", function (e) { var $target = $(e.target); var tapData = $target.data("tapData"); //不處理含有disable class的對象 if ($target.hasClass("disable")) return; //記錄信息 tapData.state = "move"; tapData.isMoved = 1; tapData.touchStartTime = 0; $target.data("tapData", tapData); //點擊效果 if(tapData.$hover) tapData.$hover.removeClass("active"); }); $(document).on("touchend", function (e) { var $target = $(e.target); var tapData = $target.data("tapData"); //不處理含有disable class的對象 if ($target.hasClass("disable")) return; //清除長按倒計時 clearTimeout(timer_langTap); //記錄信息 tapData.state = "end"; $target.data("tapData", tapData); //是否移動過 if (tapData.isMoved == 1) return; //觸摸時間 var duration = new Date().getTime() - tapData.touchStartTime; //doubleTap if(tapData.doubleTapTime == tapData.touchStartTime) { //觸發doubleTap $target.trigger("doubleTap"); if(tapData.$hover) tapData.$hover.removeClass("active"); //重置開始點擊事件(防止連續觸發doubleTap) tapData.touchStartTime = 0; $target.data("tapData", tapData); return; } //tap if(duration <= 250) { //點擊效果持續250ms timer_tap = setTimeout(function() { //tap $target.trigger("tap"); if(tapData.$hover) tapData.$hover.removeClass("active"); }, 250 - duration); return; } //觸摸時間在250ms到700ms之間 if(tapData.$hover) tapData.$hover.removeClass("active"); }); $(document).on("touchcancel", function (e) { var $target = $(e.target); var tapData = $target.data("tapData"); if(tapData.$hover) tapData.$hover.removeClass("active"); });
觸發條件:當用戶觸摸屏幕的時間達到700ms時且未移動過code
//langTap timer_langTap = setTimeout(function() { var tapData = $target.data("tapData"); if(tapData.state != "start") return; $target.trigger("langTap"); if(tapData.$hover) tapData.$hover.removeClass("active"); }, 700);
觸發條件:用戶在250ms內連續觸摸屏幕兩次對象
//doubleTap if(tapData.preTouchStartTime && tapData.touchStartTime - tapData.preTouchStartTime < 250) { //doubleTap tapData.doubleTapTime = tapData.touchStartTime; //記錄信息 $target.data("tapData", tapData); //清除timer_tap clearTimeout(timer_tap); return; }
自定義tap和模擬hover效果的原理在上兩篇文章中都有說明,這裏就再也不贅述了(主要是不知道該怎麼描述了(-_-))。事件
文章有什麼不對的地方,望你們指正。歡迎交流!rem