详解如何在Vue里建立长按指令
您是否曾想过按住按钮几秒钟才能在Vue应用程序中执行某个功能?
您是否曾想在应用程序上创建一个按钮,通过按一次(或按住按钮的整个输入)来清除单个输入?
如果你曾有过这些想法,很好,我也是。那么恭喜你看到了这篇文章。
本文将解释如何通过按下(或按住)按钮来执行功能和删除输入。
首先,我将解释如何在VanillaJS中实现这一目标。然后,为它创建一个Vue指令。
那么,让我们开始吧。
原理
为了实现长按,用户需要按住按钮几秒钟。
要在代码中复制它,我们需要在按下鼠标“单击”按钮时监听,启动计时器,不管我们希望用户在执行函数之前按住按钮,并在时间设置之后执行该功能。
非常简单!但是,我们需要知道用户何时按住该按钮。
怎么做
当用户单击按钮时,在单击事件之前会触发另外两个事件:mousedown和mouseup。
当用户按下鼠标按钮时会调用mousedown事件,而当用户释放该按钮时会调用mouseup事件。
我们需要做的就是:
发生mousedown事件后启动计时器。
清除该计时器,并且在2secs标记之前触发mouseup事件后不执行该函数。即完整点击事件。
只要计时器在到达那个时间之前没有被清除,我们就会发现mouseup事件没有被触发-我们可以说用户没有释放按钮。因此,它被认为是长按,然后我们可以继续执行所述功能。
实际操作
让我们深入研究代码并完成这项工作。
首先,我们必须定义3件事,即:
variable用于存储计时器。
start函数启动计时器。
cancel函数取消定时器
变量
这个变量基本上保存了setTimeout的值,所以我们可以在发生mouseup事件时取消它。
letpressTimer=null;
我们将变量设置为null,这样我们就可以检查变量,以便知道当前是否有一个活动定时器,然后才能取消它。
启动功能
该函数由setTimeout组成,它基本上是Javascript中的一种方法,它允许我们在函数中声明的特定持续时间之后执行函数。
请记住,在创建click事件的过程中,会触发两个事件。但我们需要启动计时器的是mousedown事件。因此,如果是单击事件,我们不需要启动计时器。
//Createtimeout(runfunctionafter1s) letstart=(e)=>{ //Makesuretheeventtriggerisn'taclickevent if(e.type==='click'&&e.button!==0){ return; } //Makesurewedon'tcurrentlyhaveasetTimeoutrunning //beforestartinganother if(pressTimer===null){ pressTimer=setTimeout(()=>{ //Executesoemthing!!! },1000) } }
取消功能
这个函数基本上就是名字所说的,取消了调用start函数时创建的setTimeout。
要取消setTimeout,我们将在javascript中使用clearTimeout方法,该方法基本上清除了使用setTimeout()设置的计时器方法。
在使用clearTimeout之前,我们首先需要检查pressTimer变量是否设置为null。如果它未设置为null,则表示存在活动计时器。所以,我们需要清除计时器,你猜对了,将pressTimer变量设置为null。
letcancel=(e)=>{ //Checkiftimerhasavalueornot if(pressTimer!==null){ clearTimeout(pressTimer) pressTimer=null } }
一旦mouseup事件被触发,就会调用此函数。
设置触发器
剩下的就是将事件监听器添加到要添加长按效果的按钮上。
addEventListener("mousedown",start); addEventListener("click",cancel);
总而言之,我们有:
//Definevariable letpressTimer=null; //Createtimeout(runfunctionafter1s) letstart=(e)=>{ if(e.type==='click'&&e.button!==0){ return; } if(pressTimer===null){ pressTimer=setTimeout(()=>{ //Executesomething!!! },1000); } } //CancelTimeout letcancel=(e)=>{ //Checkiftimerhasavalueornot if(pressTimer!==null){ clearTimeout(pressTimer); pressTimer=null; } } //selectelementwithidlongPressButton letel=document.getElementById('longPressButton'); //AddEventlisteners el.addEventListener("mousedown",start); //Canceltimeoutsifthiseventshappen el.addEventListener("click",cancel); el.addEventListener("mouseout",cancel);
将它全部包装在Vue指令中
在创建Vue指令时,Vue允许我们在组件的全局或本地定义指令,但在本文中我们将使用全局路由。
让我们构建完成此任务的指令。
首先,我们必须声明自定义指令的名称。
Vue.directive('longpress',{ }
这基本上注册了一个名为v-longpress的全局自定义指令.
接下来,我们使用一些参数添加bindhook函数,这允许我们引用元素指令绑定,获取传递给指令的值并标识使用该指令的组件。
Vue.directive('longpress',{ bind:function(el,binding,vNode){ } }
接下来,我们在bind函数中添加我们的长按javascript代码。
Vue.directive('longpress',{ bind:function(el,binding,vNode){ //Definevariable letpressTimer=null //Definefuntionhandlers //Createtimeout(runfunctionafter1s) letstart=(e)=>{ if(e.type==='click'&&e.button!==0){ return; } if(pressTimer===null){ pressTimer=setTimeout(()=>{ //Executesomething!!! },1000) } } //CancelTimeout letcancel=(e)=>{ //Checkiftimerhasavalueornot if(pressTimer!==null){ clearTimeout(pressTimer) pressTimer=null } } //AddEventlisteners el.addEventListener("mousedown",start); //Canceltimeoutsifthiseventshappen el.addEventListener("click",cancel); el.addEventListener("mouseout",cancel); } })
接下来,我们需要添加一个函数来运行将传递给longpress指令的方法。
//LongPressvuedirective Vue.directive('longpress',{ bind:function(el,binding,vNode){ //Definevariable letpressTimer=null //Definefuntionhandlers //Createtimeout(runfunctionafter1s) letstart=(e)=>{ if(e.type==='click'&&e.button!==0){ return; } if(pressTimer===null){ pressTimer=setTimeout(()=>{ //Executefunction handler() },1000) } } //CancelTimeout letcancel=(e)=>{ //Checkiftimerhasavalueornot if(pressTimer!==null){ clearTimeout(pressTimer) pressTimer=null } } //RunFunction consthandler=(e)=>{ //Executemethodthatispassedtothedirective binding.value(e) } //AddEventlisteners el.addEventListener("mousedown",start); //Canceltimeoutsifthiseventshappen el.addEventListener("click",cancel); el.addEventListener("mouseout",cancel); } })
现在我们可以在我们的Vue应用程序中使用该指令,该指令将正常工作,直到用户添加的值不是指令值中的函数。所以我们必须通过在发生这种情况时警告用户来防止这种情况。
要警告用户,我们将以下内容添加到bind函数:
//Makesureexpressionprovidedisafunction if(typeofbinding.value!=='function'){ //Fetchnameofcomponent constcompName=vNode.context.name //passwarningtoconsole letwarn=`[longpress:]providedexpression'${binding.expression}'isnotafunction,buthastobe` if(compName){warn+=`Foundincomponent'${compName}'`} console.warn(warn) }
最后,这个指令也适用于触控设备。所以我们为touchstart,touchend&touchcancel添加事件监听器。
把所有东西放在一起:
Vue.directive('longpress',{ bind:function(el,binding,vNode){ //Makesureexpressionprovidedisafunction if(typeofbinding.value!=='function'){ //Fetchnameofcomponent constcompName=vNode.context.name //passwarningtoconsole letwarn=`[longpress:]providedexpression'${binding.expression}'isnotafunction,buthastobe` if(compName){warn+=`Foundincomponent'${compName}'`} console.warn(warn) } //Definevariable letpressTimer=null //Definefuntionhandlers //Createtimeout(runfunctionafter1s) letstart=(e)=>{ if(e.type==='click'&&e.button!==0){ return; } if(pressTimer===null){ pressTimer=setTimeout(()=>{ //Runfunction handler() },1000) } } //CancelTimeout letcancel=(e)=>{ //Checkiftimerhasavalueornot if(pressTimer!==null){ clearTimeout(pressTimer) pressTimer=null } } //RunFunction consthandler=(e)=>{ binding.value(e) } //AddEventlisteners el.addEventListener("mousedown",start); el.addEventListener("touchstart",start); //Canceltimeoutsifthiseventshappen el.addEventListener("click",cancel); el.addEventListener("mouseout",cancel); el.addEventListener("touchend",cancel); el.addEventListener("touchcancel",cancel); } })
现在引用我们的Vue组件:
{{value}}
如果您希望了解有关自定义指令的更多信息,可以使用的钩子函数,可以传递给此钩子函数的参数,函数缩写。伟大的家伙@vuejs在解释它这里方面做得很好。
成功!!!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。