JS如何利用定时器实现长按事件
本篇文章由:http://xinpure.com/js-how-to-use-timer-press-event/
JS 原生事件并没有长按事件,但是我们可以利用一些原有的事件,来实现长按事件
任务需求
最近在工作上遇到一个特殊的需求,就是需要实现长按来增加或者减少数值
这就类似于,购物车中的物品数量的加减按钮,单击按钮物品数量相应增加或者减少一个数量,利用长按来实现快速增加或者减少物品数量
思考方法
在知道这个需求之后,开始还是比较茫然的
虽然在之前我也在一些购物 APP 里见到过这种长按的功能,但是在 JS 里似乎并没有长按事件
后来我就在想,怎么样利用现有的一些事件来实现这一功能呢?
这个时候我想到了 mousedown
和 mouseup
这两个事件
当时我就想,如果在 mousedown
事件触发的时候,利用 setTimeout
或者 setInterval
定时增加或者减少数值
然后在 mouseup
事件触发的时候,利用 clearTimeout
或者 clearInterval
清除定时器
这样是不是就能实现这样的需求呢?
实践想法
既然有了想法,就要付诸实践
我写了个例子来测试这个想法,结果却并没有想得这么简单
当我通过鼠标按住按钮之后,数值是不断的增加或者减少,但是即使我松开鼠标,数值却并没有停止,而是依然为不断的增加或者减少
这时我就疑惑了,理论上说,在 mouseup
事件触发之后,定时器应该是已经被清除的,为何没有清除呢?
带着疑惑,我开始了 Google
Google
将我指引到了 Jquery Mobile 库
这个类库实现了一个 taphold
事件,就是我想要的长按事件
既然已经有了类似的实现,我就在想,是不是我哪里想错了?
然后我就查看了 Jquery Mobile
关于 taphold
的源码
看完源码后,我惊喜的发现,原来他也是利用 setTimeout
来实现的这一事件,证明我的想法是对的!
带着惊喜,我开始分析我思考的不足的地方。
最后我发现,原来是我没有做好对事件的监听
我只是单纯的绑定了 mousedown
和 mouseup
两个事件,这是我在 JS 事件处理上的不足
完善实现
知道了问题之后,我就开始修改之前写的例子
采用 Jquery Mobile
库对事件的处理方式,来实现这个长按的功能,并且也根据自身的需求进行修改
在修改的过程中,我发现了一个问题,就是当我长按一个按钮的时候,如果我移动鼠标,长按事件也会一直持续下去,并且放开鼠标也不会停止
在翻看 JS 事件的之后,我找到了 mouseleave
这个事件,就是当鼠标离开按钮之后,会触发这个事件,加上之后,问题也得己解决。
为了兼容移动设备,我加上了对 touchstart
、touchend
、touchcencel
几个事件的监听
本来也想加上 touchleave
事件,来处理触摸时用户移动到按钮外的情况,但是似乎这个事件已经被废弃掉了:
This event was a proposal in an early version of the specification and has not been implemented. Do not rely on it. —— MDN
也尝试了使用 touchmove
事件来代替,但是似乎会影响用户体验
因为添加了这个事件之后,就算是在按钮上触摸移动,也会触发 touchmove
事件
所以如果是用户误操作的话,也会中止长按操作。
不过,touch
事件并不会像 mouse
事件一样,触摸移动到按钮外之后再放开手指,事件还是可以正常处理,并不会影响使用
最终代码
JS Code
var tapParams = {
timer: {},
element: {},
tapStartTime: 0,
type: 'increment'
};
function clearTapTimer() {
clearTimeout(tapParams.timer);
}
function clearTapHandlers() {
clearTapTimer();
$(tapParams.element).unbind('mouseup', clearTapTimer)
.unbind('mouseleave', clearTapHandlers);
/* 移动设备 */
$(tapParams.element).unbind('touchend', clearTapTimer)
.unbind('touchcencel', clearTapHandlers);
}
function tapEvent(aEvent, aType) {
/* 阻止默认事件并解除冒泡 */
aEvent.preventDefault();
aEvent.stopPropagation();
tapParams = {
element: aEvent.target,
startTime: new Date().getTime() / 1000,
type: aType
};
$(tapParams.element).bind('mouseup', clearTapTimer)
.bind('mouseleave', clearTapHandlers);
/* 移动设备 */
$(tapParams.element).bind('touchend', clearTapTimer)
.bind('touchcencel', clearTapHandlers);
changeNumber();
}
function changeNumber() {
var currentDate = new Date().getTime() / 1000;
var intervalTime = currentDate - tapParams.startTime;
/* 根据长按的时间改变数值变化幅度 */
if (intervalTime < 1) {
intervalTime = 0.5;
}
var secondCount = intervalTime * 10;
if (intervalTime == 3) {
secondCount = 50;
}
if (intervalTime >= 4) {
secondCount = 100;
}
var numberElement = $('.number');
var currentNumber = parseInt(numberElement.val());
if (tapParams.type == 'increment') {
currentNumber += 1;
} else if (tapParams.type == 'decrement') {
currentNumber -= 1;
}
numberElement.val(currentNumber <= 0 ? 1 : currentNumber);
tapParams.timer = setTimeout('changeNumber()', 1000 / secondCount);
}
HTML Code
<div class="container">
<div class="section">
<div class="decrement" onmousedown="tapEvent(event, 'decrement')" ontouchstart="tapEvent(event, 'decrement')">-</div>
<input class="number" value="1">
<div class="increment" onmousedown="tapEvent(event, 'increment')" ontouchstart="tapEvent(event, 'increment')">+</div>
</div>
</div>
CSS Code
.section {
display: -webkit-flex;
display: flex;
-webkit-justify-content: center;
justify-content: center;
-webkit-flex-flow: row nowrap;
flex-flow: row nowrap;
-webkit-align-items: center;
align-items: center;
height: 30px;
width: 130px;
font-size: 16px;
}
.number {
-webkit-flex: 1;
flex: 1;
width: 30px;
height: 30px;
border: 1px solid #000;
display: inline-block;
border-radius: 5px;
margin: 0 10px;
text-align: center;
}
.decrement, .increment {
width: 30px;
height: 30px;
border: 1px solid #000;
display: inline-block;
border-radius: 5px;
text-align: center;
line-height: 28px;
cursor: pointer;
font-size: 20px;
}
效果展示
JS如何利用定时器实现长按事件的更多相关文章
- 【转】原生js实现移动端h5长按事件
$("#target").on({ touchstart: function(e) { // 长按事件触发 timeOutEvent = setTimeout(function() ...
- cocos2d-x C++ (利用定时器自定义屏幕双击事件函数)
//GameScene.h #include "cocos2d.h" USING_NS_CC; class GameScene : public cocos2d::Layer { ...
- webview长按事件js监听
做app开发时,用到了webview,需要监听webview的长按事件,使用原生的js处理监听如下: ; //定时器 //开始按 function gtouchstart() { timeOutEve ...
- js 触发长按事件
为网站添加触摸功能 <button id="btn1">长按触发</button> <button id="btn2">长按 ...
- VUE长按事件
PS:在开发中常常会有长按事件的需求,这里我简单的介绍几种长按事件的需求 需求一:长按数字累加或者累减 HTML: <div class="mui-numbox" data- ...
- js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符
js中对arry数组的各种操作小结 最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以说啊 ...
- 移动端H5长按事件 vue自定义指令
import Vue from 'vue' Vue.directive('longpress', function (el, binding){ var timer = null; var start ...
- 移动端h5模拟长按事件
为啥写这篇文章 最近接了个需求,要求长按某个标签显示删除一个悬浮的删除按钮.这个需求其实在app上很常见,但是在移动端h5中,我们没有长按的事件,所以就需要自己模拟这个事件了. 大概效果如下: ps: ...
- 微信小程序区分点击,长按事件
在上代码之前,微信小程序点击事件,长按事件的触发顺序需要我们了解一下下 事务分类 touchstart:手指触摸 longtap:手指触摸后后,超过350ms离开 touchend:手指触摸动作结束 ...
随机推荐
- 《疯狂iOS讲义(下)——iPhone/iPad高级应用与手游开发(含CD光盘1张)》
<疯狂iOS讲义(下)——iPhone/iPad高级应用与手游开发(含CD光盘1张)> 基本信息 作者: 李刚 肖文吉 出版社:电子工业出版社 ISBN:9787121224379 ...
- cas4.0 session中返回更多的用户信息
实现思路: 新增AccoutAttributeDao类继承StubPersonAttributeDao,重写getPerson方法.实际应用中我们只需要修改getPersion方法中的内容,根据实际情 ...
- 操作系统Day1地址空间与地址生成
1.地址空间分成(1)物理地址空间 (2)逻辑地址空间二者之间的关系:*逻辑地址空间的生成:程序——>汇编-->linker——>loader*物理地址的生成:内存的逻辑地址空间会有 ...
- BZOJ 4145 [AMPPZ2014] The Prices 解题报告
感觉也是一个小清新题.. 我们考虑设立状态 $Dp[i][s]$ 表示考虑了前 $i$ 个商店后,购买状态为 $s$ 的最小花费. 转移的话就枚举每个商店 $i$,首先令: $$Dp[i][s] = ...
- Linux学习杂记
近期一口气看完了韩顺平老师讲的Linux视频教程,自己也在学习的过程中做了些笔记,记载例如以下.希望帮助到一些喜欢研究Linux的同学.也算是在云端备份一下笔记吧.以免电脑出现不可控的因素而遗失自己的 ...
- 6 cocos2dx粒子效果,类图关系,系统原生粒子和自己定义粒子效果,粒子编译器软件,爆炸粒子效果,烟花效果,火焰效果,流星效果,漩涡粒子效果,雪花效果,烟雾效果,太阳效果,下雨效果
1 粒子 演示样例 2 类图关系 3 系统原生粒子 CCParticleSystem 全部粒子系统的父类 CCParticleSystemPoint. CCParticleSystemQuad ...
- [4] 圆锥(Cone)图形的生成算法
顶点数据的生成 bool YfBuildConeVertices ( Yreal radius, Yreal height, Yuint slices, YeOriginPose originPose ...
- 你可能不知道的5 个强大的HTML5 API 函数
HTML5提供了一些非常强大的JavaScript和HTML API,来帮助开发者构建精彩的桌面和移动应用程序.本文将介绍5个新型的API,希望对你的开发工作有所帮助. 1. 全屏API(Fulls ...
- CSS3中background属性的调整
CSS3对于background做了一些修改,最明显的一个就是采用设置多背景,不但添加了4个新属性,并且还对目前的属性进行了调整增强. 1.多个背景图片 在css3里面,你可以再一个标签元素里应用多个 ...
- IIS-网站发布之后访问HTTP 错误 403.14 - Forbidden
这种问题一般是因为页面本身发生了错误的原因导致的,这个时候先开启[目录浏览]功能 开通目录浏览之后再重新访问,就能看到相应的错误了,再去进行相应的解决就可以了.