Stories

Detail Return Return

完整版移動端滑動事件封裝 - Stories Detail

image

touchEvent

基於Jquery擴展在移動端產生的事件,包含,單次觸摸事件,兩次觸摸事件,長按事件,滑屏事件,向上滑動事件,向下滑動事件,向左滑動事件,向右滑動事件

B4lry8.png

預覽

地址預覽
https://hangjob.github.io/touchEvent/index.html

事件類型

單次觸摸事件
$(el).tap
tap: function(element, fn) {
        var startTx, startTy;
        v_on(element, 'touchstart', function(e) {
            var touches = e.touches[0];
            startTx = touches.clientX;
            startTy = touches.clientY;
        }, false);

        v_on(element, 'touchend', function(e) {
            var touches = e.changedTouches[0],
                endTx = touches.clientX,
                endTy = touches.clientY;
            // 在部分設備上 touch 事件比較靈敏,導致按下和鬆開手指時的事件座標會出現一點點變化
            if (Math.abs(startTx - endTx) < 6 && Math.abs(startTy - endTy) < 6) {
                fn();
            }
        }, false);
    }
兩次觸摸事件
$(el).doubleTap
doubleTap: function(element, fn) {
        var isTouchEnd = false,
            lastTime = 0,
            lastTx = null,
            lastTy = null,
            firstTouchEnd = true,
            body = document.body,
            dTapTimer, startTx, startTy, startTime;
        v_on(element, 'touchstart', function(e) {
            if (dTapTimer) {
                clearTimeout(dTapTimer);
                dTapTimer = null;
            }
            var touches = e.touches[0];
            startTx = touches.clientX;
            startTy = touches.clientY;
        }, false);
        v_on(element, 'touchend', function(e) {
            var touches = e.changedTouches[0],
                endTx = touches.clientX,
                endTy = touches.clientY,
                now = Date.now(),
                duration = now - lastTime;
            // 首先要確保能觸發單次的 tap 事件
            if (Math.abs(startTx - endTx) < 6 && Math.abs(startTx - endTx) < 6) {
                // 兩次 tap 的間隔確保在 500 毫秒以內
                if (duration < 301) {
                    // 本次的 tap 位置和上一次的 tap 的位置允許一定範圍內的誤差
                    if (lastTx !== null &&
                        Math.abs(lastTx - endTx) < 45 &&
                        Math.abs(lastTy - endTy) < 45) {
                        firstTouchEnd = true;
                        lastTx = lastTy = null;
                        fn();
                    }
                } else {
                    lastTx = endTx;
                    lastTy = endTy;
                }
            } else {
                firstTouchEnd = true;
                lastTx = lastTy = null;
            }
            lastTime = now;
        }, false);
        // 在 iOS 的 safari 上手指敲擊屏幕的速度過快,
        // 有一定的機率會導致第二次不會響應 touchstart 和 touchend 事件
        // 同時手指長時間的touch不會觸發click
        if (~navigator.userAgent.toLowerCase().indexOf('iphone os')) {
            v_on(body, 'touchstart', function(e) {
                startTime = Date.now();
            }, true);
            v_on(body, 'touchend', function(e) {
                var noLongTap = Date.now() - startTime < 501;
                if (firstTouchEnd) {
                    firstTouchEnd = false;
                    if (noLongTap && e.target === element) {
                        dTapTimer = setTimeout(function() {
                            firstTouchEnd = true;
                            lastTx = lastTy = null;
                            fn();
                        }, 400);
                    }
                } else {
                    firstTouchEnd = true;
                }
            }, true);
            // iOS 上手指多次敲擊屏幕時的速度過快不會觸發 click 事件
            v_on(element, 'click', function(e) {
                if (dTapTimer) {
                    clearTimeout(dTapTimer);
                    dTapTimer = null;
                    firstTouchEnd = true;
                }
            }, false);
        }
}
長按事件
$(el).longTap
longTap: function(element, fn) {
        var startTx, startTy, lTapTimer;
        v_on(element, 'touchstart', function(e) {
            if (lTapTimer) {
                clearTimeout(lTapTimer);
                lTapTimer = null;
            }
            var touches = e.touches[0];
            startTx = touches.clientX;
            startTy = touches.clientY;
            lTapTimer = setTimeout(function() {
                fn(startTx, startTy);
            }, 1000);
        }, false);
        v_on(element, 'touchmove', function(e) {
            var touches = e.touches[0],
                endTx = touches.clientX,
                endTy = touches.clientY;
            if (lTapTimer && (Math.abs(endTx - startTx) > 5 || Math.abs(endTy - startTy) > 5)) {
                clearTimeout(lTapTimer);
                lTapTimer = null;
            }
        }, false);
        v_on(element, 'touchend', function(e) {
            if (lTapTimer) {
                clearTimeout(lTapTimer);
                lTapTimer = null;
            }
        }, false);
}
滑屏事件
$(el).swipe
向上滑動事件
$(el).swipeUp
向下滑動事件
$(el).swipeDown
向左滑動事件
$(el).swipeLeft
向右滑動事件
$(el).swipeRight

$.fn.extend()擴展

jQuery.fn是jQuery的原型對象,其extend()方法用於為jQuery的原型添加新的屬性和方法。這些方法可以在jQuery實例對象上調用

jQuery.fn.extend({
    tap: function(fn) {
        return touchEvent.tap(jQuery(this)[0], fn);
    },
    doubleTap: function(fn) {
        return touchEvent.doubleTap(jQuery(this)[0], fn);
    },
    longTap: function(fn) {
        return touchEvent.longTap(jQuery(this)[0], fn);
    },
    swipe: function(fn) {
        return touchEvent.swipe(jQuery(this)[0], fn);
    },
    swipeLeft: function(fn) {
        return touchEvent.swipeLeft(jQuery(this)[0], fn);
    },
    swipeRight: function(fn) {
        return touchEvent.swipeRight(jQuery(this)[0], fn);
    },
    swipeUp: function(fn) {
        return touchEvent.swipeUp(jQuery(this)[0], fn);
    },
    swipeDown: function(fn) {
        return touchEvent.swipeDown(jQuery(this)[0], fn);
    }
});

如何使用

$('.container').swipeRight((res) => {
   ulDom.append(createLi(`向右滑動了${res}px`));
})

$('.container').swipe((x, y) => {
   ulDom.append(createLi(`滑屏事件,X軸滑動了${x}px,Y軸滑動了${y}px`));
})
...

Github

https://github.com/hangjob/touchEvent

如有疑問

掃描公眾號,回覆:加羣
https://www.vipbic.com/weixin.html

user avatar grewer Avatar yinzhixiaxue Avatar qingzhan Avatar banana_god Avatar yixiyidong Avatar libubai Avatar kitty-38 Avatar lovecola Avatar gaozhipeng Avatar tangzhiyuan Avatar bencjl Avatar dtux Avatar
Favorites 44 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.