在这里插入图片描述

原来的遥控是采用按键形式,但是说是用户体验不好,但是虚拟摇杆又没有搞定,这里采用第二种方案,增加按钮长按功能,但是用的elementUI里面又没有提供长按功能的button,网上找的方案是自定义vue指令,关键是通过定时器实现长按功能:(为了便于理解,我把原文步骤都放过来,最后提供我修改后的完整代码,原文链接在最后)
原理如下:
长按,即用户按下按钮并持续按住几秒钟,即触发长按功能。那么,要实现这样的功能关键点在于我们需要知道的是用户什么时候按下按钮和什么时候松开按钮。幸运的是:浏览器在当用户点击鼠标时提供给了我们两个事件: mousedown 和 mouseup。当用户按下鼠标时会触发 mousedown 事件,用户松开鼠标时会触发 mouseup 事件。有了这两个事件,我们只需这样做:

1.当mousedown 事件触发时,启动一个计时器,开始计时。

2.设定一个时间阈值,比如2秒。在时间阈值内如果 mouseup 事件被触发了,即认为这是一次普通的单击,不执行长按功能函数并清除定时器。反之,超出时间阈值后 mouseup 事件才被触发,即认为用户在长按按钮,此时执行长按功能函数。

实现:
1、计时器变量
首先,我们定义一个变量timer,用于存储定时器,并且设置初始值为null;

let timer = null

2、启动函数
该函数是当浏览器监听到mousedown事件触发后执行的回调函数,该函数主要作用是创建并启动定时器,并且在设定的时间阈值内如果mouseup还未触发,则执行长按功能函数。函数代码如下:

var start = function (e) {
        // 如果是点击事件,不启动计时器,直接返回
        if (e.type === 'click'){
            return
        }
        if (timer == null){
            // 创建定时器 ( 2s之后执行长按功能函数 )
            timer = setTimeout(function () {
                //执行长按功能函数
                longFunc()
            },2000)
        }
    }

3、取消函数
该函数是当浏览器监听到mouseup事件触发后执行的回调函数,该函数主要作用是清除定时器。函数代码如下:

var cancel = function () {
        if (timer !== null){
            clearTimeout(timer)
            timer = null
        }
    }

4、设置事件监听器
设置事件监听器,用于监听mousedown、mouseup和click事件,分别执行不同的回调函数。

// 添加事件监听器

el.addEventListener("mousedown", start);

// 长按事件取消,取消计时器

el.addEventListener("click", cancel);

el.addEventListener("mouseout", cancel);

5、定义vue指令
有了上面的工作后,我们就可以定义vue指令了:

Vue.directive('longpress', function (el, binding){
            var timer = null;
            var start = function (e) {
                // 如果是点击事件,不启动计时器,直接返回
                if (e.type === 'click'){
                    return
                }
                if (timer == null){
                    // 创建定时器 ( 2s之后执行长按功能函数 )
                    timer = setTimeout(function () {
                        //执行长按功能函数
                        binding.value()
                    },2000)
                }
            }
            var cancel = function () {
                if (timer !== null){
                    clearTimeout(timer)
                    timer = null
                }
            }

            // 添加事件监听器
            el.addEventListener("mousedown", start);

            // 取消计时器
            el.addEventListener("click", cancel);
            el.addEventListener("mouseout", cancel);
    })

代码中el表示指令绑定的元素,binding表示传递给指令的值,详细请参考官方文档自定义指令

6、使用指令
到这里,我们就可以在模板中愉快的使用指令啦。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    {{value}}
    <button @click="incrementPlusOne" v-longpress="incrementPlusTen">该按钮具有长按功能哦!!!</button>
</div>
<script src="vue.js"></script>
<script type="text/javascript">
    Vue.directive('longpress', function (el, binding){
            var timer = null;
            var start = function (e) {
                // 如果是点击事件,不启动计时器,直接返回
                if (e.type === 'click'){
                    return
                }
                if (timer == null){
                    // 创建定时器 ( 2s之后执行长按功能函数 )
                    timer = setTimeout(function () {
                        //执行长按功能函数
                        binding.value()
                    },2000)
                }
            }
            var cancel = function () {
                if (timer !== null){
                    clearTimeout(timer)
                    timer = null
                }
            }

            // 添加事件监听器
            el.addEventListener("mousedown", start);

            // 取消计时器
            el.addEventListener("click", cancel);
            el.addEventListener("mouseout", cancel);
    })
    new Vue({
        el:"#app",
        data(){
            return{
                value:10
            }
        },
        methods: {
            // 增加1
            incrementPlusOne() {
                this.value++
            },
            // 增加10
            incrementPlusTen() {
                this.value += 10
            }

        }
    })
</script>
</body>
</html>

以上就是原文所有步骤了,上面就是一个单html页面,但是项目用的脚手架搭建、,下面我展示我的代码
从上往下来看:页面
在这里插入图片描述
首先为前进后退四个按钮绑定btnNum这个值,为1,2,3,4,再绑定长按指令 v-longpress=“incrementPlusTen”

在script里面,首先要引入vue:import Vue from 'vue';
在这里插入图片描述
不然会报错 Vue is not defined
在这里插入图片描述
在data里面初始化value值为10,btnNum为0;
在这里插入图片描述
在methods里面增加方法:(incrementPlusOne这个我没用到)
在这里插入图片描述
script最后是长按指令:

//长按指令
Vue.directive('longpress', 
   { bind:function (el, binding, vnode){
            var timer = null;
            var myVar =null;
            var start = function (e) {
                // 如果是点击事件,不启动计时器,直接返回
                if (e.type === 'click'){
                    return
                }
                if (timer == null){
                    // 创建定时器 ( 2s之后执行长按功能函数 )
                    timer = setTimeout(function () {
                        //执行长按功能函数
                        myVar = setInterval(function(){vnode.context.remoteCon(el.getAttribute("btnNum"),this.roId); }, 2000);
                        binding.value(e)
                    },2000)
                }
            }
            var cancel = function () {
                if (timer !== null){
                    clearTimeout(timer)
                    timer = null
                    
                    clearInterval(myVar);
                }
            }

            // 添加事件监听器
            el.addEventListener("mousedown", start);

            // 取消计时器
            el.addEventListener("click", cancel);
            el.addEventListener("mouseout", cancel);
    }
    })

这里我主要是增加了自己的长按功能函数,这个长按我是要调用remoteCon这个函数来发送相应的指令,我在它本身的setTimeout定时器里面嵌套了setInterval定时器,

两种定时器区别:

setInterval(表达式,时间):页面载入后,每经过指定毫秒值后执行指定表达式,是间隔多次执行的
setTimeout(表达式,时间):页面载入后,经过指定毫秒值后执行指定表达式,只执行一次

remoteCon是 method 中的方法,直接使用会报错,
在这里插入图片描述
在指令后面加参数vnode,通过vnode.context.remoteCon();就可以使用methods中的方法,

remoteCon(num,roId),其中两个参数,一个是按钮属性,1,2,3,4对应前进后退,roId对应机器人id,其中可以使用this.roId获取机器人id,但是始终无法获取num的值,(说是可以通过 binding.value(e)获取值,但是我没搞明白)所以通过一开始定义过btnNum这个值,用el.getAttribute("btnNum")来获取
在这里插入图片描述
另外我还发现,按照原博主的代码,在执行长按方法时候,start会执行四次,导致后面调用方法都是四次一调,四次一调,这里我修改了一下,在start的function前面加了bind:如下图,反括号加在末尾
在这里插入图片描述

长按效果 第一个参数为方向键绑定的num,第二个为机器人id:
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐