手撸一个vue自定义插件 vue-touch

3 篇文章 0 订阅
// 自定义vue指令插件
class VueTouchEvent {
    /**
     * @param  {DOM} el
     * @param  {
     *      name:指令名,不包括 v- 前缀。
     *      arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo
     *      value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
     * } binding
     * @description:自定义元素的触摸事件如点击长按不放,上下左右滑动
     */
    constructor(el, binding) {
        this.domEL = el;
        this.binding = binding;
        this.touchType = this.binding.arg;
        if (typeof this.binding.value !== 'function') throw new Error('v-touch 必须指定函数')
        this.callback = this.binding.value;
        this.init(this.touchType)
    }
    init(touchtype) {
        switch (touchtype) {
            case 'longtap':
                this.bindLongTap()
                break;
            case 'swiper-up':
                this.bindSwiperUp()
                break;
            case 'swiper-down':
                this.bindSwiperDown()
                break;
            case 'swiper-left':
                this.bindSwiperLeft()
                break;
            case 'swiper-right':
                this.bindSwiperRight()
                break
            default:
        }
    }
    bindLongTap() {
        const dom = this.domEL;
        dom.addEventListener('touchstart', () => {
            // 记录点击时间
            this.pressTimer = null
            this.pressTimer = setTimeout(() => {
                clearTimeout(this.pressTimer)
                    // 超过一秒执行callback
                this.callback(this.domEL)
            }, 1000)
        })
        dom.addEventListener('touchend', () => {
            clearTimeout(this.pressTimer)
            this.pressTimer = null
        })
    }
    bindSwiperUp() {
        this.domEL.addEventListener('touchstart', (e) => {
            this.clientY = Math.ceil(e.changedTouches[0].clientY)

        })
        this.domEL.addEventListener('touchend', (e) => {
            if (this.clientY - e.changedTouches[0].clientY > 50) {
                this.callback(this)
            }
            this.clientY = null;
        })
    }
    bindSwiperDown() {
        this.domEL.addEventListener('touchstart', (e) => {
            this.clientY = Math.ceil(e.changedTouches[0].clientY)
        })
        this.domEL.addEventListener('touchend', (e) => {
            if (this.clientY - e.changedTouches[0].clientY < -50) {
                this.callback(this)
            }
            this.clientY = null;
        })
    }
    bindSwiperLeft() {
        this.domEL.addEventListener('touchstart', (e) => {
            this.clientX = Math.ceil(e.changedTouches[0].clientX)
        })
        this.domEL.addEventListener('touchend', (e) => {
            if (this.clientX - e.changedTouches[0].clientX > 50) {
                this.callback(this)
            }
            this.clientX = null;
        })
    }
    bindSwiperRight() {
        this.domEL.addEventListener('touchstart', (e) => {
            this.clientX = Math.ceil(e.changedTouches[0].clientX)
        })
        this.domEL.addEventListener('touchend', (e) => {
            if (this.clientX - e.changedTouches[0].clientX < -50) {
                this.callback(this)
            }
            this.clientX = null;
        })
    }
}


const touch = function(vue, opotions) {
    vue.directive('touch', {
        bind: function(el, binding) {
            new VueTouchEvent(el, binding)
        }
    })
};
// 插件注入
Vue.use(touch)
 <div id="vm" v-cloak>
        <div>
            <img v-touch:longtap="callback" src="./images/logo.png" alt="" srcset="">
        </div>
    </div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值