1

背景

是这样子滴,有时候我们用vue框架的时候,要用到很多手势,像tap、doubletap、longtap......,当然现在网上有很多手势裤什么的,拿来改一下也是可以实现自己想要的效果滴,我是希望用vue 的时候类似于

<p @tap="aaa" @longtap="bbb">{{msg}}---长按(longtap)点击(tap)事件</p>

这么用那好了,左思右想写了一个小栗子,用来抛砖引玉。

原理

首先要理解js的自定义事件。Events 可以使用 Event构造函数 创建如下:

// 事件对象
var event = new Event('build');

// 监听事件
elem.addEventListener('build', function (e) { ... }, false);

// 分发事件
elem.dispatchEvent(event);

当然可以,添加自定义数据

var event = new CustomEvent('build', { 'detail': elem.dataset.time });

好了,看了上面的原理之后直接上源码,简单封装一个tap和longtap事件,

实现

先写个打架都熟悉的vue的小代码

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title></title>
        <style type="text/css">
            p{
                background: #168dd2;
                padding: 15px;
                color: #FFFFFF;
            }
        </style>
        <script type="text/javascript" src="vue.js"></script>
        <script type="text/javascript" src="tap.js"></script>
    </head>

    <body>
        <div id="app">
            <p @tap="aaa" @longtap="bbb">{{msg}}---长按(longtap)点击(tap)事件</p>
            
            <p @tap="aaa">{{msg}}---点击(tap)事件</p>
            
            <p @longtap="bbb">{{msg}}---长按(longtap)事件</p>
            
            <p @touchstart="aaa">{{msg}}---touchstart事件</p>
            
            <p>{{msg}}---没有事件跟风用~~~</p>
        </div>
    </body>
    <script type="text/javascript">
        new Vue({
            el: '#app',
            data: {
                msg: 'hello'
            },
            methods: {
                aaa: function(e) {
                    console.log(e);
                },
                bbb: function(e) {
                    console.log('loooongtap');
                    console.log(e);
                }
            }
        })
    </script>

</html>

上面引入了一个tap.js, 下面我们就去补全这个js就好了。

tap.js

(function() {
    var TOUCHSTART, TOUCHMOVE, TOUCHEND;
    if(typeof(window.ontouchstart) != 'undefined') {
        TOUCHSTART = 'touchstart';
        TOUCHEND = 'touchend';
        TOUCHMOVE = 'touchmove';

    } else if(typeof(window.onmspointerdown) != 'undefined') {
        TOUCHSTART = 'MSPointerDown';
        TOUCHEND = 'MSPointerUp';
        TOUCHMOVE = 'MSPointerMove';
    } else {
        TOUCHSTART = 'mousedown';
        TOUCHEND = 'mouseup';
        TOUCHMOVE = 'mousemove';
    }

    function tap(node) {
        var x, y, startTime = 0,
            endTime = 0,
            in_dis = false;
        node.oncontextmenu = function() {
            return false;
        }
        node.addEventListener(TOUCHSTART, function(e) {
            x = e.touches[0].pageX;
            y = e.touches[0].pageY;
            startTime = (new Date()).getTime();
        });

        node.addEventListener(TOUCHEND, function(e) {
            e.stopPropagation();
            e.preventDefault();
            var curx = e.changedTouches[0].pageX;
            var cury = e.changedTouches[0].pageY;
            if(Math.abs(curx - x) < 6 && Math.abs(cury - y) < 6) {
                in_dis = true;
            } else {
                in_dis = false;
            }
            endTime = (new Date()).getTime();
            if(endTime - startTime > 300 && in_dis) {
                e.target.dispatchEvent(new CustomEvent('longtap', {
                    'detail': e
                }));
            } else {
                e.target.dispatchEvent(new CustomEvent('tap', {
                    'detail': e
                }));
            }
        });
    }

    tap(document);
})();

也先不管了 直接挂载到document上面(人懒~~~~)。
这样子就好了 直接预览下效果,

图片描述

能正常调用aaa(), bbb(),还行还行~~~!!!

酱紫之后会不会好一点????,写的不好~~~道友们轻喷~~~~


naice
2k 声望161 粉丝

很多事情不是因为有希望才去坚持,而是坚持了才有希望。