JavaScript 实现暴击事件
2016-03-29 22:32
701 查看
在许多场景中,我们可能会遇到需要处理一种快速多次触发某事件,并处于某种阈值时,执行某一指定操作。例如,双击(即快速按鼠标左键两次)或更多击、连按键盘某键、某方法被执行数次等。其中,双击有对应的事件可以注册;然而,更多的情况是没有的类似事件方便我们注册使用的。那么,现在只能依靠我们勤劳的双手,来创造一个支持该功能的任务,并且该任务需要具有以下功能。
可以在任务中绑定一个方法,以便在暴击后被调用。
该任务可以被多次执行,包括也可以在已知事件中触发。
只有当任务在短时间内执行到指定次数后,所注册的方法才会被调用。
当短时间内执行了过多的次数,所注册的方法将不再被调用。
短时间的界定方式是,通过指定一个连续两次任务执行间隔的最长时间,来进行控制。
那么,这该如何实现呢?
首先,我们需要定义一个函数,其接受一个用于设置选项的参数,该函数的作用是生成一个任务,该任务实际上应该也是一个函数,并接受一个可选的参数,用来传递额外的信息给绑定的方法,然后返回一个布尔值来指示当前的执行是否调用了绑定的方法。
这个选项参数应当包含以下方法和属性。
process 方法,即该任务所绑定的方法。
包含两个参数:第一个是整数型,表示第几次执行;第二个参数可选,任意类型,可用于接受在任务执行时,所传入的额外参数。
该方法无返回值。
start 属性,可选,整数型,即短时间内第几次触发时调用任务中绑定的方法。
count 属性,可选,整数型,即绑定的方法在一轮快速触发时最多可被调用多少次。
timeout 属性,可选,整数型,即任意两次连续触发的最长时限,以微秒为单位。超出该时限后,几位另外一轮触发,计数器清零。
thisArg 属性,可选,任意型,即所绑定方法在被调用时的 this 参数。
很明显,当 start 为被设置或被设置为0,并且 count 属性未被设置时,所绑定的任务不会被执行次数限制。于是我们可以在 multipleHit 函数中进行以下改写。
而除此以外,我们至少需要加上计时器和最近一次执行的时间记录了。
那么,理论上,由此该返回以下函数。
显然,在上述返回的函数中,在调用该绑定的方法前,我们应当先校检查上次执行的时间,以确定是否应该执行,同时记录本次执行的时间。
同理,对本轮执行的次数也需要检验和递增。
于是,我们就得到了以下代码。
现在我们来测试一下。把以下代码放到页面加载之后。
当你在页面中快速点击,你会在浏览器控制台中看到,只有快速连击3以上才会显示记录,当出现了100次之后,就不会再有了,除非停一会儿,那就又重新开始计算了。
文章类型及复杂度:Web 进阶。
节选翻译自 MSDN 博文 Multiple Hit Task,内容有所调整。
http://blogs.msdn.com/b/kingcean/archive/2016/03/21/multiple-hit-task.aspx
可以在任务中绑定一个方法,以便在暴击后被调用。
该任务可以被多次执行,包括也可以在已知事件中触发。
只有当任务在短时间内执行到指定次数后,所注册的方法才会被调用。
当短时间内执行了过多的次数,所注册的方法将不再被调用。
短时间的界定方式是,通过指定一个连续两次任务执行间隔的最长时间,来进行控制。
那么,这该如何实现呢?
首先,我们需要定义一个函数,其接受一个用于设置选项的参数,该函数的作用是生成一个任务,该任务实际上应该也是一个函数,并接受一个可选的参数,用来传递额外的信息给绑定的方法,然后返回一个布尔值来指示当前的执行是否调用了绑定的方法。
function multipleHit(options) { // ToDo: Implement it. return null; }
这个选项参数应当包含以下方法和属性。
process 方法,即该任务所绑定的方法。
包含两个参数:第一个是整数型,表示第几次执行;第二个参数可选,任意类型,可用于接受在任务执行时,所传入的额外参数。
该方法无返回值。
start 属性,可选,整数型,即短时间内第几次触发时调用任务中绑定的方法。
count 属性,可选,整数型,即绑定的方法在一轮快速触发时最多可被调用多少次。
timeout 属性,可选,整数型,即任意两次连续触发的最长时限,以微秒为单位。超出该时限后,几位另外一轮触发,计数器清零。
thisArg 属性,可选,任意型,即所绑定方法在被调用时的 this 参数。
很明显,当 start 为被设置或被设置为0,并且 count 属性未被设置时,所绑定的任务不会被执行次数限制。于是我们可以在 multipleHit 函数中进行以下改写。
if (!options.start && options.count == null) { return function (modelArg) { options.process.call(options.thisArg, 0, modelArg); return true; }; }
而除此以外,我们至少需要加上计时器和最近一次执行的时间记录了。
var count = 0; var time = null;
那么,理论上,由此该返回以下函数。
return function (modelArg) { options.process.call(options.thisArg, count - 1, modelArg); return true; };
显然,在上述返回的函数中,在调用该绑定的方法前,我们应当先校检查上次执行的时间,以确定是否应该执行,同时记录本次执行的时间。
var timespan = time != null ? new Date().getTime() - time.getTime() : null; time = new Date(); if (timespan == null || timespan > options.timeout) { count = 1; return false; }
同理,对本轮执行的次数也需要检验和递增。
count++; var start = !!options.start ? options.start : 0; if (count < start || (options.count != null && options.count <= count - start)) return false;最后,别忘了在函数前加上为空判断。
if (!options || !options.process || options.count === 0) return null;
于是,我们就得到了以下代码。
/**
* Generates a multiple hit task.
* @param options The options to load.
*/
function multipleHit(options) {
if (!options || !options.process || options.count === 0) return null;
if (!options.start && options.count == null) { return function (modelArg) { options.process.call(options.thisArg, 0, modelArg); return true; }; }
var count = 0; var time = null;return function (modelArg) {
var timespan = time != null ? new Date().getTime() - time.getTime() : null; time = new Date(); if (timespan == null || timespan > options.timeout) { count = 1; return false; }
count++; var start = !!options.start ? options.start : 0; if (count < start || (options.count != null && options.count <= count - start)) return false;
options.process.call(options.thisArg, count - 1, modelArg);
return true;
};
}
现在我们来测试一下。把以下代码放到页面加载之后。
var task = multipleHit({ timeout: 300, start: 3, count: 100, process: function (index, model) { console.debug(index.toString() + " at " + model); } }); document.body.addEventListener("click", function (ev) { task(new Date().toLocaleDateString()); }, false);
当你在页面中快速点击,你会在浏览器控制台中看到,只有快速连击3以上才会显示记录,当出现了100次之后,就不会再有了,除非停一会儿,那就又重新开始计算了。
文章类型及复杂度:Web 进阶。
节选翻译自 MSDN 博文 Multiple Hit Task,内容有所调整。
http://blogs.msdn.com/b/kingcean/archive/2016/03/21/multiple-hit-task.aspx
相关文章推荐
- javascript--this机制
- js笔记2 Dom节点的操作
- jsp中img显示本地图片
- return阻止js继续向下执行
- ExtJs4.2—Window组件
- 使用cJSON解析JSON字符串
- javascript自定义右键菜单,js自定义右键删除——和派孔明
- JSP九大对象
- 让你分分钟学会 javascript 闭包
- JavaScript学习笔记2(草稿)
- JavaScript语言精粹——继承
- HTML+servlet+js(使用ajax传参) 出现中文乱码
- javascript 跨域请求
- ExtJs中getCmp、getDom、Get的区别
- JS编写冒泡排序法和二分查找
- javascript 几种常见设计模式
- js 页面值变动监听
- JSP简单练习-EL获取表单数据
- [置顶] JavaScript操作Cookie——高级篇
- JSON 使用