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. 前端之CSS基础及使用方法

    CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素. 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染). CSS语法 CSS实例 ...

  2. java不支持多继承

    java不支持多继承,但支持多重继承,即一个类只能继承一个类,使用extends关键字 一个类可以实现多个接口,接口之间用逗号分隔,使用implements关键字 一个接口可以继承多个其他接口,接口之 ...

  3. 使用Newspaper3k框架快速抓取文章信息

    一.框架介绍 Newspaper是一个python3库,但是Newspaper框架并不适用于实际工程类新闻信息爬取工作,框架不稳定,爬取过程中会有各种bug,例如获取不到url.新闻信息等,但对于想获 ...

  4. IP的分类以及子网划分、网络设置

    前言 整个因特网就是一个单一的.抽象的的网络.IP地址就是给因特网上的每一个主机(或路由器)的每一个接口分配一个在全世界范围是唯一的32位的标识符.IP地址的结构使我们可以在因特网上很方便的进行寻址. ...

  5. UVA - 12099 The Bookcase

    No wonder the old bookcase caved under the massive piles of books Tom had stacked on it. He had bett ...

  6. Be Nice!要善良

    [1]  It is nice to be important, but it is more important to be nice. [2]  What simple act of kindne ...

  7. 移动端Rem布局注意事项

    1.布局的总体结构框架:      2.注意事项: (a):如果是左右两栏的布局方式,须在article的同级加一个aside: 因为是同级,所以必须设置同样的样式:而且他俩的父级,也就是sectio ...

  8. CS184.1X 计算机图形学导论 罗德里格斯公式推导

    罗德里格斯公式推导 图1(复制自wiki) 按照教程里,以图1为例子,设k为旋转轴,v为原始向量. v以k为旋转轴旋转,旋转角度为θ,旋转后的向量为vrot. 首先我们对v进行分解,分解成一个平行于k ...

  9. NOIP_TG

    本博客主要记录一些在刷题的途中遇到的一些巧妙的题目 砝码称重 一开始想到可以DP递推标记能凑成的数量 但发现同一种砝码可能有多个于是想多开一维状态存当前还剩多少砝码 真是愚蠢至极 直接把所有砝码单独看 ...

  10. PowerSploit-CodeExecution(代码执行)脚本渗透实战

    首先介绍一下国外大牛制作的Powershell渗透工具PowerSploit,上面有很多powershell攻击脚本,它们主要被用来渗透中的信息侦察.权限提升.权限维持. 项目地址:https://g ...