博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何在Vue里建立长按指令
阅读量:6263 次
发布时间:2019-06-22

本文共 7820 字,大约阅读时间需要 26 分钟。

clipboard.png

您是否曾想过按住按钮几秒钟才能在Vue应用程序中执行某个功能?

您是否曾想在应用程序上创建一个按钮,通过按一次(或按住按钮的整个输入)来清除单个输入?

如果你曾有过这些想法,很好,我也是。那么恭喜你看到了这篇文章。

本文将解释如何通过按下(或按住)按钮来执行功能和删除输入。

首先,我将解释如何在VanillaJS中实现这一目标。然后,为它创建一个Vue指令。

那么,让我们开始吧。

原理

为了实现长按,用户需要按住按钮几秒钟。

要在代码中复制它,我们需要在按下鼠标“单击”按钮时监听,启动计时器,不管我们希望用户在执行函数之前按住按钮,并在时间设置之后执行该功能。

非常简单!但是,我们需要知道用户何时按住该按钮。

怎么做

当用户单击按钮时,在单击事件之前会触发另外两个事件: mousedown 和 mouseup 。

当用户按下鼠标按钮时会调用 mousedown 事件,而当用户释放该按钮时会调用mouseup事件。

我们需要做的就是:

发生mousedown事件后启动计时器。

清除该计时器,并且在2secs标记之前触发mouseup事件后不执行该函数。即完整点击事件。

只要计时器在到达那个时间之前没有被清除,我们就会发现mouseup事件没有被触发 - 我们可以说用户没有释放按钮。因此,它被认为是长按,然后我们可以继续执行所述功能。

实际操作

让我们深入研究代码并完成这项工作。

首先,我们必须定义3件事,即:

variable 用于存储计时器。

start 函数启动计时器。

cancel 函数取消定时器

变量

这个变量基本上保存了setTimeout的值,所以我们可以在发生mouseup事件时取消它。

let pressTimer = null;

我们将变量设置为null,这样我们就可以检查变量,以便知道当前是否有一个活动定时器,然后才能取消它。

启动功能

该函数由setTimeout组成,它基本上是Javascript中的一种方法,它允许我们在函数中声明的特定持续时间之后执行函数。

请记住,在创建click事件的过程中,会触发两个事件。但我们需要启动计时器的是mousedown事件。因此,如果是单击事件,我们不需要启动计时器。

// Create timeout ( run function after 1s )let start = (e) => {        // Make sure the event trigger isn't a click event    if (e.type === 'click' && e.button !== 0) {        return;    }    // Make sure we don't currently have a setTimeout running    // before starting another    if (pressTimer === null) {        pressTimer = setTimeout(() => {            // Execute soemthing !!!        }, 1000)    }}

取消功能

这个函数基本上就是名字所说的,取消了调用start函数时创建的setTimeout。

要取消setTimeout,我们将在javascript中使用 clearTimeout 方法,该方法基本上清除了使用setTimeout()设置的计时器方法。

在使用clearTimeout之前,我们首先需要检查 pressTimer 变量是否设置为null。如果它未设置为null,则表示存在活动计时器。所以,我们需要清除计时器,你猜对了,将 pressTimer 变量设置为 null

let cancel = (e) => {    // Check if timer has a value or not    if (pressTimer !== null) {        clearTimeout(pressTimer)        pressTimer = null    }}

一旦 mouseup 事件被触发,就会调用此函数。

设置触发器

剩下的就是将事件监听器添加到要添加长按效果的按钮上。

addEventListener("mousedown", start);addEventListener("click", cancel);

总而言之,我们有:

// Define variablelet pressTimer = null;// Create timeout ( run function after 1s )let start = (e) => {    if (e.type === 'click' && e.button !== 0) {        return;    }    if (pressTimer === null) {        pressTimer = setTimeout(() => {            // Execute something !!!        }, 1000);    }}// Cancel Timeoutlet cancel = (e) => {    // Check if timer has a value or not    if (pressTimer !== null) {        clearTimeout(pressTimer);        pressTimer = null;    }}// select element with id longPressButtonlet el = document.getElementById('longPressButton');// Add Event listenersel.addEventListener("mousedown", start);// Cancel timeouts if this events happenel.addEventListener("click", cancel);el.addEventListener("mouseout", cancel);

将它全部包装在Vue指令中

在创建Vue指令时,Vue允许我们在组件的全局或本地定义指令,但在本文中我们将使用全局路由。

让我们构建完成此任务的指令。

首先,我们必须声明自定义指令的名称。

Vue.directive('longpress', {  }

这基本上注册了一个名为 v-longpress的全局自定义指令.

接下来,我们使用一些参数添加bind hook函数 ,这允许我们引用元素指令绑定,获取传递给指令的值并标识使用该指令的组件。

Vue.directive('longpress', {  bind: function (el, binding, vNode) {      }}

接下来,我们在bind函数中添加我们的长按javascript代码。

Vue.directive('longpress', {    bind: function (el, binding, vNode) {        // Define variable        let pressTimer = null        // Define funtion handlers        // Create timeout ( run function after 1s )        let start = (e) => {            if (e.type === 'click' && e.button !== 0) {                return;            }            if (pressTimer === null) {                pressTimer = setTimeout(() => {                    // Execute something !!!                }, 1000)            }        }        // Cancel Timeout        let cancel = (e) => {            // Check if timer has a value or not            if (pressTimer !== null) {                clearTimeout(pressTimer)                pressTimer = null            }        }        // Add Event listeners        el.addEventListener("mousedown", start);        // Cancel timeouts if this events happen        el.addEventListener("click", cancel);        el.addEventListener("mouseout", cancel);    }})

接下来,我们需要添加一个函数来运行将传递给 longpress 指令的方法。

// Long Press vue directiveVue.directive('longpress', {    bind: function (el, binding, vNode) {        // Define variable        let pressTimer = null        // Define funtion handlers        // Create timeout ( run function after 1s )        let start = (e) => {            if (e.type === 'click' && e.button !== 0) {                return;            }            if (pressTimer === null) {                pressTimer = setTimeout(() => {                    // Execute function                    handler()                }, 1000)            }        }        // Cancel Timeout        let cancel = (e) => {            // Check if timer has a value or not            if (pressTimer !== null) {                clearTimeout(pressTimer)                pressTimer = null            }        }        // Run Function        const handler = (e) => {            // Execute method that is passed to the directive            binding.value(e)        }        // Add Event listeners        el.addEventListener("mousedown", start);        // Cancel timeouts if this events happen        el.addEventListener("click", cancel);        el.addEventListener("mouseout", cancel);            }})

现在我们可以在我们的Vue应用程序中使用该指令,该指令将正常工作,直到用户添加的值不是指令值中的函数。所以我们必须通过在发生这种情况时警告用户来防止这种情况。

要警告用户,我们将以下内容添加到bind函数:

// Make sure expression provided is a functionif (typeof binding.value !== 'function') {  // Fetch name of component  const compName = vNode.context.name  // pass warning to console  let warn = `[longpress:] provided expression '${binding.expression}' is not a function, but has to be`  if (compName) { warn += `Found in component '${compName}' ` }  console.warn(warn)}

最后,这个指令也适用于触控设备。所以我们为 touchstart , touchend & touchcancel 添加事件监听器。

把所有东西放在一起:

Vue.directive('longpress', {    bind: function (el, binding, vNode) {        // Make sure expression provided is a function        if (typeof binding.value !== 'function') {            // Fetch name of component            const compName = vNode.context.name            // pass warning to console            let warn = `[longpress:] provided expression '${binding.expression}' is not a function, but has to be`            if (compName) { warn += `Found in component '${compName}' ` }            console.warn(warn)        }        // Define variable        let pressTimer = null        // Define funtion handlers        // Create timeout ( run function after 1s )        let start = (e) => {            if (e.type === 'click' && e.button !== 0) {                return;            }            if (pressTimer === null) {                pressTimer = setTimeout(() => {                    // Run function                    handler()                }, 1000)            }        }        // Cancel Timeout        let cancel = (e) => {            // Check if timer has a value or not            if (pressTimer !== null) {                clearTimeout(pressTimer)                pressTimer = null            }        }        // Run Function        const handler = (e) => {            binding.value(e)        }        // Add Event listeners        el.addEventListener("mousedown", start);        el.addEventListener("touchstart", start);        // Cancel timeouts if this events happen        el.addEventListener("click", cancel);        el.addEventListener("mouseout", cancel);        el.addEventListener("touchend", cancel);        el.addEventListener("touchcancel", cancel);    }})

现在引用我们的Vue组件:

如果您希望了解有关自定义指令的更多信息,可以使用的钩子函数,可以传递给此钩子函数的参数,函数缩写。伟大的家伙@vuejs在解释它方面做得很好。

成功 !!!

插件:,一个用于网络应用的DVR(录像机)

clipboard.png

是一个前端日志记录工具,可让您像在自己的浏览器中一样重放问题。LogRocket不是猜测错误发生的原因,也不是要求用户提供屏幕截图和日志转储,而是让您重播会话以快速了解出现了什么问题。它适用于任何应用程序,无论框架如何,并且具有从Redux,Vuex和@ngrx / store记录其他上下文的插件。

除了记录Redux操作和状态之外,LogRocket还记录控制台日志,JavaScript错误,堆栈跟踪,带有标题+正文的网络请求/响应,浏览器元数据和自定义日志。它还使用DOM来记录页面上的HTML和CSS,重新创建即使是最复杂的单页应用程序的像素完美视频。

附:

转载地址:http://pckpa.baihongyu.com/

你可能感兴趣的文章
iOS开发中的错误整理,(百思项目,指示器位置)设置控件尺寸和点坐标,先设置尺寸,再设置点坐标...
查看>>
(C/C++学习)7.数组及其访问方式
查看>>
LeetCode——Intersection of Two Linked Lists
查看>>
对拍——我目前可以找到的最简写法
查看>>
js之广告弹出自动关闭
查看>>
axios请求requestBody和formData
查看>>
PSQL_标准API和Interface基本的用法和比较(概念)
查看>>
网站目录
查看>>
APUE-文件和目录(七)符号链接
查看>>
CSS 简介
查看>>
System Verilog基础(二)
查看>>
2018/11/26 Samba服务器配置
查看>>
2018/12/08 PAT刷题 L1-034 点赞
查看>>
如何改变TextBox.PassWordChar的值 转
查看>>
css的工作原理
查看>>
【pip】的安装
查看>>
内存泄漏及其检测工具
查看>>
QT Model based vs Item based
查看>>
[Leetcode]669 Trim a Binary Search Tree
查看>>
Linux C Programing - Arguments(2)
查看>>