1.前言

在word中,当我们需要删除一大段文本的时候,我们按一下键盘上的退格键,就会删除一个字,当我们长按住退格键时,就会连续不停的删除,这就是键盘按键的长按功能。那么我们也想在网页中让一个按钮也具有“长按”和“单击”不同的功能,该怎样实现呢?下面我们采用vue自定义指令的方式,来实现一个长按指令。

2.原理

长按,即用户按下按钮并持续按住几秒钟,即触发长按功能。那么,要实现这样的功能关键点在于我们需要知道的是用户什么时候按下按钮和什么时候松开按钮。幸运的是:浏览器在当用户点击鼠标时提供给了我们两个事件: mousedown 和 mouseup。当用户按下鼠标时会触发 mousedown 事件,用户松开鼠标时会触发 mouseup 事件。有了这两个事件,我们只需这样做:

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

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

3.实现

3.1 计时器变量

首先,我们定义一个变量timer,用于存储定时器,并设置初始值未null。

let timer = null

3.2 启动函数

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

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

3.3 取消函数

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

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

3.4 设置事件监听器

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

// 添加事件监听器

el.addEventListener("mousedown", start);

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

el.addEventListener("click", cancel);

el.addEventListener("mouseout", cancel);

4. 定义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表示传递给指令的值,详细请参考官方文档自定义指令

5. 使用指令

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

<!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>

6.适配移动端

其实,按钮长按功能在移动触屏终端远比PC端实用的多,要想让这个指令也适配移动触屏端,我们只需在监听一下移动端特有的触摸事件 touchstart、touchend 和 touchcancel 事件即可。

// 添加事件监听器
el.addEventListener("mousedown", start);
el.addEventListener("touchstart", start);
// 取消计时器
el.addEventListener("click", cancel);
el.addEventListener("mouseout", cancel);
el.addEventListener("touchend", cancel);
el.addEventListener("touchcancel", cancel);

(完)

vue自定义长按指令的更多相关文章

  1. vue 自定义拖拽指令

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. vue自定义指令

    Vue自定义指令: Vue.directive('myDr', function (el, binding) { el.onclick =function(){ binding.value(); } ...

  3. Vue 自定义图片懒加载指令v-lazyload

    Vue是可以自定义指令的,最近学习过程中遇见了一个需要图片懒加载的功能,最后参考了别人的代码和思路自己重新写了一遍.以下将详细介绍如何实现自定义指令v-lazyload. 先看如何使用这个指令: &l ...

  4. vue 自定义指令的使用案例

    参考资料: 1. vue 自定义指令: 2. vue 自定义指令实现 v-loading: v-loading,是 element-ui 组件库中的一个用于数据加载过程中的过渡动画指令,项目中也很少需 ...

  5. Vue -自定义指令&钩子函数

    除了核心功能默认内置的指令,Vue也允许注册自定义指令 页面加载后,让文本框自动获取焦点,原生js做法是获取文本框元素后调用focus()方法,但Vue不建议手动操作DOM元素,所以此时要自定义指令 ...

  6. vue自定义指令(Directive中的clickoutside.js)的理解

    阅读目录 vue自定义指令clickoutside.js的理解 回到顶部 vue自定义指令clickoutside.js的理解 vue自定义指令请看如下博客: vue自定义指令 一般在需要 DOM 操 ...

  7. Vue自定义指令报错:Failed to resolve directive: xxx

    Vue自定义指令报错 Failed to resolve directive: modle 这个报错有2个原因: 1.指令单词拼错 2.Vue.directive() 这个方法没有写在 new Vue ...

  8. vue自定义指令clickoutside使用以及扩展用法

    vue自定义指令clickoutside使用以及扩展用法 产品使用vue+element作为前端框架.在功能开发过程中,难免遇到使用element的组件没办法满足特殊的业务需要,需要对其进行定制,例如 ...

  9. vue自定义指令clickoutside扩展--多个元素的并集作为inside

    都是个人理解,如果发现错误,恳请大家批评指正,谢谢.还有我说的会比较啰嗦,因为是以自身菜鸡水平的视角来记录学习理解的过程,见谅. 1.前言 产品使用vue+element作为前端框架.在功能开发过程中 ...

随机推荐

  1. 浅谈sqlserver的事务锁

    锁的概述 一. 为什么要引入锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 丢失更新 A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统 ...

  2. NOIP2011计算系数;

    #include<cmath> #include<algorithm> #include<stdio.h> #include<iostream> #de ...

  3. 寻找子串位置<codevs>

    KMP板子题; 如果不会可以参考其他算法书 代码: #include<iostream> #include<stdio.h> #include<stdlib.h> ...

  4. System NT Kernel & System占用CPU 12%左右 终极解决方案,原来是更新惹的祸

    任务管理器发现 system进程持续占用12%左右的cpu,网上搜索到的很多方法均无效 误打误撞发现了这个方法,亲测可用 卸载系统补丁(KB41000347),提升10%的cpu性能 卸载补丁前:  ...

  5. 《java编程思想》P22-P37(第二章一切都是对象)

    1.JAVA操纵的标识符实际上是对象的一个"引用";如String s;里的s是String类的引用并非对象. 2.程序运行时,有五个不同的地区可以存储数据. (1)寄存器:最快的 ...

  6. 不就是SELECT COUNT语句吗,竟然能被面试官虐的体无完肤

    数据库查询相信很多人都不陌生,所有经常有人调侃程序员就是CRUD专员,这所谓的CRUD指的就是数据库的增删改查. 在数据库的增删改查操作中,使用最频繁的就是查询操作.而在所有查询操作中,统计数量操作更 ...

  7. meterpreter读取hash明文记录

    今天测试某个站点时读hash老出错 这里做下读hash的笔记 进去meterpreter后getuid一 1 2 meterpreter > getuid Server username: NT ...

  8. USACO环绕岛屿Surround the Islands 并查集 枚举暴力

    题目描述 Farmer John has bought property in the Caribbean and is going to try to raise dairy cows on a b ...

  9. 使用git如何规范地向主线提交代码

    使用git向主干分支合并代码通常采用两种方式:第一种是merge,第二种是利用BeyondCompare等工具进行比对,将差异合并到主干: 通过merge合并代码出现冲突时,并不清楚谁的修改和谁的修改 ...

  10. opencv::opencv_createsamples.exe

    opencv_createsamples.exe 用来生成正样本vec的,用来准备训练用的正样本数据和测试数据.他的输出为以 *.vec 为扩展名的文件,该文件以二进制方式存储图像. Usage: o ...