菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
496
0

vue.js实现移动端长按事件,处理长按事件和click事件冲突,长按安卓机支持震动

原创
05/13 14:22
阅读数 18822
vue.js自定义指令实现长按,安卓支持震动
export default {
    install(Vue, options = {
        time: 1000
    }) {
        Vue.directive('longpress', {
            bind: function (el, binding, vNode) {
                // 确保提供的表达式是函数
                if (typeof binding.value !== 'function') {
                    // 获取组件名称
                    const compName = vNode.context.name;
                    // 将警告传递给控制台
                    let warn = `[longpress:] provided expression '${binding.expression}' is not afunction, but has to be `;
                    if (compName) {
                        warn += `Found in component '${compName}' `;
                    }
                    console.warn(warn);
                }
                var startX, startY, startTime;
                // 定义变量
                let pressTimer = null;
                // 定义函数处理程序
                // 创建计时器( 1秒后执行函数 )
                let start = (e) => {
                    if (e.type === 'click' && e.button !== 0) {
                        return;
                    }
                    e.preventDefault();
                    // 记录下触发的坐标和时间
                    startTime = (new Date()).getTime();
                    startX = e.targetTouches[0].clientX;
                    startY = e.targetTouches[0].clientY;
                    /**
                    *  注意:此处处理长按震动效果,经测试IOS目前不支持震动
                    **/
                     if (pressTimer === null) {
                        pressTimer = setTimeout(() => {
                            navigator.vibrate = navigator.vibrate
                                || navigator.webkitVibrate
                                || navigator.mozVibrate
                                || navigator.msVibrate;

                            if (navigator.vibrate) {
                                // 支持
                                navigator.vibrate(200);
                            }
                            // 执行函数
                            handler();
                        }, options.time);
                    }
            
                };
                // 取消计时器
                let cancel = (e) => {
                  /**
                   *  注意:此处处理与click事件的冲突(小于300ms可以识别为点击事件的范围 然后判断触摸点的移动距离)
                   **/
                    e.preventDefault();
                    var now = (new Date()).getTime();
                    if (now - startTime < 300) {
                        var x = (Math.abs(startX - e.changedTouches[0].clientX) < 30);
                        var y = (Math.abs(startY - e.changedTouches[0].clientY) < 30);
                        if (x && y) {
                            e.changedTouches[0].target.click();
                        }
                    }
                    // 检查计时器是否有值
                    if (pressTimer !== null) {
                        clearTimeout(pressTimer);
                        pressTimer = null;
                    }
                };
                // 运行函数
                const handler = (e) => {
                    // 执行传递给指令的方法
                    binding.value(e);
                };
                /**
                   *  注意:禁止浏览器长按出菜单
                 **/
                document.oncontextmenu = function (e) {
                    e.preventDefault();
                    return false;
                };
                // 添加事件监听器
                el.addEventListener('mousedown', start);
                el.addEventListener('touchstart', start);
                // 取消计时器
                el.addEventListener('mouseout', cancel);
                el.addEventListener('touchend', cancel);
                el.addEventListener('touchcancel', cancel);
            }
        });
    }
};

另一种优雅的实现方法

发表评论

0/200
496 点赞
0 评论
收藏