解决移动端 300ms click 问题

本文介绍了一个用于监听触屏点击事件的JavaScript库,该库能够跨浏览器和设备工作,包括现代浏览器、MSIE 9及以上版本、Firefox等,并且支持AMD和ES6模块加载方式。库中定义了Tap类,通过监听touchstart、touchmove、touchend、touchcancel、mousedown、mousemove和mouseup等事件,实现了一种统一的触屏点击事件处理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

tap.js

(function(global, factory) {
    "use strict";
    if (typeof define === 'function' && define.amd) {
        // 支持AMD ,使用 require.js
        define(function() {
            return (global.Tap = factory(global, global.document));
        });
    } else if (typeof exports === 'object') {
        // 支持 es6 module
        module.exports = factory(global, global.document);
    } else {
        global.Tap = factory(global, global.document);
    }
})(typeof window !== 'undefined' ? window : this, function(window, document) {
    "use strict";

    function Tap(el) {
        this.el = typeof el === "object" ? el : document.getElementById(el);
        this.moved = false;
        this.startX = 0;
        this.startY = 0;
        this.hasTouchEventOccured = false;
        this.el.addEventListener("touchstart", this, false);
        this.el.addEventListener("mousedown", this, false);
    }

    Tap.prototype.leftButton = function(event) {
        // modern & MSIE>=9, FireFox(all)
        if ('button' in event) {
            return event.buttons === 1;
        } else {
            return 'which' in event ? event.which === 1 : event.button === 1;
        }
    }

    Tap.prototype.start = function(e) {
        if (e.type === 'touchstart') {
            this.hasTouchEventOccured = true;
            this.el.addEventListener("touchmove", this, false);
            this.el.addEventListener("touchend", this, false);
            this.el.addEventListener("touchcancel", this, false);
        } else if (e.type === 'mousedown' && this.leftButton(e)) {
            this.el.addEventListener('mousemove', this, false);
            this.el.addEventListener('mouseup', this, false);
        }

        this.moved = false;
        this.startX = e.type === 'touchstart' ? e.touches[0].clientX : e.clientX;
        this.startY = e.type === 'touchstart' ? e.touches[0].clientY : e.clientY;
    };


    Tap.prototype.move = function(e) {
        // if finger moves more than 10px flag to cancel
        var x = e.type === 'touchmove' ? e.touches[0].clientX : e.clientY;
        var y = e.type === 'touchmove' ? e.touches[0].clientY : e.clientY;

        if (Math.abs(x - this.startX) > 10 || Math.abs(y - this.startY) > 10) {
            this.moved = true;
        }
    };

    Tap.prototype.end = function(e) {
        var evt;
        this.el.removeEventListener('touchmove', this, false);
        this.el.removeEventListener('touchend', this, false);
        this.el.removeEventListener('touchcancel', this, false);
        this.el.removeEventListener('mouseup', this, false);
        this.el.removeEventListener('mousemove', this, false);

        if (!this.moved) {
            try {
                evt = new window.CustomEvent('tap', {
                    // 创建事件 tap
                    // 支持冒泡,取消冒泡功能
                    bubbles: true,
                    cancelable: true,
                })
            } catch (e) {
                evt = document.createEvent("Event");
                evt.initEvent('tap', true, true);
            }
        }

        // 阻止冒泡
        e.stopPropagation();

        // dispatchEvent returns false if any handler calls preventDefault,
        if (!e.target.dispatchEvent(evt)) {
            e.preventDefault();
        }
    };

    Tap.prototype.cancel = function() {
        this.hasTouchEventOccured = false;
        this.moved = false;
        this.startX = 0;
        this.startY = 0;
    };

    Tap.prototype.destroy = function() {
        this.el.removeEventListener('touchstart', this, false);
        this.el.removeEventListener('touchmove', this, false);
        this.el.removeEventListener('touchend', this, false);
        this.el.removeEventListener('touchcancel', this, false);
        this.el.removeEventListener('mousedown', this, false);
        this.el.removeEventListener('mouseup', this, false);
        this.el.removeEventListener('mousemove', this, false);
    };

    Tap.prototype.handleEvent = function() {
        switch (e.type) {
            case 'touchstart':
                this.start(e);
                break;
            case 'touchmove':
                this.move(e);
                break;
            case 'touchend':
                this.end(e);
                break;
            case 'touchcancel':
                this.cancel(e);
                break;
            case 'mousedown':
                this.start(e);
                break;
            case 'mouseup':
                this.end(e);
                break;
            case 'mousemove':
                this.move(e);
                break;
        }
    };
    return Tap;
});
博客
v8worker
05-08 2959
05-06 2942
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值