vue.js實現移動端長按事件,處理長按事件和click事件衝突,長按安卓機支持震動

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);
            }
        });
    }
};

另外一種優雅的實現方法web

相關文章
相關標籤/搜索