Vue 移动端常用tap事件封装

基于Vue的移动端项目,有些时间原生并没用提供,需要我们自己手动封装,可以封装一些自定义指令来供全局使用。

本文封装了 tap, swipe, swipeleft, swiperight, swipedowm, swipedown, swipeup, longtap, 在项目中基本上也够用了

代码如下

function vueTouch(el, binding, type) {
    var _this = this;
    this.obj = el;
    this.binding = binding;
    this.touchType = type;
    this.vueTouches = {
        x: 0,
        y: 0
    };
    this.vueMoves = true;
    this.vueLeave = true;
    this.longTouch = true;

    this.vueCallBack = typeof(binding.value) == "object" ? binding.value.fn : binding.value;

    this.obj.addEventListener("touchstart", function(e) {
        _this.start(e);
    }, false);

    this.obj.addEventListener("touchmove", function(e) {
        _this.move(e);
    }, false);

    this.obj.addEventListener("touchend", function(e) {
        _this.end(e);
    }, false);
};
vueTouch.prototype = {
    start(e) {
        e.preventDefault(); // 长按时阻止默认菜单,IOS还需要 -webkit-touch-callout: none; 来禁用默认菜单
        this.vueMoves = true;
        this.vueLeave = true;
        this.longTouch = true;
        this.vueTouches = {
            x: e.changedTouches[0].pageX,
            y: e.changedTouches[0].pageY
        };
        this.time = setTimeout(function() {
            if(this.vueLeave && this.vueMoves) {
                this.touchType == "longtap" && this.vueCallBack(this.binding.value, e);
                this.longTouch = false;
            };
        }.bind(this), 1000);
    },
    end(e) {
        var disX = e.changedTouches[0].pageX - this.vueTouches.x;
        var disY = e.changedTouches[0].pageY - this.vueTouches.y;
        clearTimeout(this.time);
        if(Math.abs(disX) > 10 || Math.abs(disY) > 100) {
            this.touchType == "swipe" && this.vueCallBack(this.binding.value, e);
            if(Math.abs(disX) > Math.abs(disY)) {
                if(disX > 10) {
                    this.touchType == "swiperight" && this.vueCallBack(this.binding.value, e);
                };
                if(disX < -10) {
                    this.touchType == "swipeleft" && this.vueCallBack(this.binding.value, e);
                };
            } else {
                if(disY > 10) {
                    this.touchType == "swipedown" && this.vueCallBack(this.binding.value, e);
                };
                if(disY < -10) {
                    this.touchType == "swipeup" && this.vueCallBack(this.binding.value, e);
                };
            };
        } else {
            if(this.longTouch && this.vueMoves) {
                this.touchType == "tap" && this.vueCallBack(this.binding.value, e);
                this.vueLeave = false
            };
        };
    },
    move(e) {
        this.vueMoves = false;
    }
};

Vue.directive("tap", {
    bind: function(el, binding) {
        new vueTouch(el, binding, "tap");
    }
});
Vue.directive("swipe", {
    bind: function(el, binding) {
        new vueTouch(el, binding, "swipe");
    }
});
Vue.directive("swipeleft", {
    bind: function(el, binding) {
        new vueTouch(el, binding, "swipeleft");
    }
});
Vue.directive("swiperight", {
    bind: function(el, binding) {
        new vueTouch(el, binding, "swiperight");
    }
});
Vue.directive("swipedown", {
    bind: function(el, binding) {
        new vueTouch(el, binding, "swipedown");
    }
});
Vue.directive("swipeup", {
    bind: function(el, binding) {
        new vueTouch(el, binding, "swipeup");
    }
});
Vue.directive("longtap", {
    bind: function(el, binding) {
        new vueTouch(el, binding, "longtap");
    }
});
原文地址:https://www.cnblogs.com/shenjp/p/9778722.html