有没有办法测量鼠标按和发布之间的毫秒数?
答案 0 :(得分:28)
您可以创建一个闭包来共享两个变量,一个用于存储开始时间,另一个用于结束时间,然后在mouseup事件中,获得差异:
(function () {
var element = document.getElementById('element'),
start, end;
element.onmousedown = function () {
start = +new Date(); // get unix-timestamp in milliseconds
};
element.onmouseup = function () {
end = +new Date();
var diff = end - start; // time difference in milliseconds
};
})();
检查此工作example。
答案 1 :(得分:15)
.timeStamp
属性中减去第一个事件的.timeStamp
属性来获取两个事件之间的时间。 new Date()
或调用Date.now()
来尝试获取事件发生的时间。这是一个比其他答案更微妙的问题,因为它可以归功于。
方法proposed by CMS's answer - 通过创建new Date()
然后从彼此中减去这些时间来获取每个处理程序中的时间 - 可能非常不准确。这种方法的问题在于,您没有比较事件发生的时间,而是在比较处理程序触发的时间。
提问者链接的文章 - John Resig的How JavaScript Timers Work - 与此处理解问题相关。 JavaScript执行是单线程的,只要JavaScript之外的某些东西触发了一些JavaScript执行 - 无论是超时触发,发生事件还是脚本加载 - JavaScript都会被添加到等待触发的回调队列中,这会得到顺序执行。在大多数浏览器中,每个浏览器选项卡都有一个JavaScript线程和一个队列。在Safari中,有一个线程完全停止,它在所有选项卡之间共享 - 这意味着一个选项卡中的慢速JavaScript可能会延迟您的事件处理程序在另一个选项卡中触发。
这导致了一些方法,如果我们尝试根据处理程序运行的时间来计算事件,我们尝试计算事件之间的时间可能会非常糟糕。请考虑以下两种情况:
第一种情况接下来会发生什么?计算成本高昂的JavaScript完成运行,然后两个事件处理程序快速连续启动。因此,如果您通过获取处理程序触发时的当前时间来对事件进行计时,则会错误地计算事件之间的时间,使其接近0毫秒。
第二种情况接下来会发生什么?当然,这一次,我们错误地将事件之间的时间计算为大约1秒,因为第二处理程序的执行被延迟了。
您可以在http://jsfiddle.net/gagLxrsc/处观察此操作。只需单击按钮,观察mousedown和mouseup之间计算的时间差总是大约1000ms。
我们可以做些什么来阻止这种情况?好吧,理想情况下,我们想要一种方法来获取事件发生的实际时间,不仅仅是其处理程序触发的时间。 DOM API是否为我们提供了这样的东西?
可能。这取决于您的浏览器。事件具有.timeStamp
属性,根据某些人对规范的解释,该属性应该提供事件发生的时间而不是处理程序触发的时间。但是,目前在所有浏览器中都不可行。
在Firefox中,.timeStamp
属性按我们希望的方式工作 - 它为mousedown或mouseup事件发生时提供时间戳,而不是在其处理程序开始执行时。但是,在Edge中,.timeStamp
属性为我们提供了处理程序触发的时间。 (当我在2014年第一次写这个答案时,Chrome也出现了这种情况,但Chrome的行为似乎已经修复了。)
对于像Edge这样的浏览器,您无法保证事件之间计算时差的正确性,因为您无法访问任何可靠有关事件发生的时间的信息。您可以通过避免执行锁定JavaScript线程的计算成本高昂的任务来减少不准确的可能性 - 事实上,尝试执行此操作无论如何,只是为了确保您的UI保持活泼当用户按下按钮时,响应并且不会延迟。但是如果你失败了,或者你正在编写库或插件代码并且不知道页面上的其他JavaScript代码是否会做任何冗长和昂贵的事情,那么不准确的风险是不可避免的 - 你会只需要容忍它,直到所有浏览器都像Firefox那样实现timeStamp
属性。不过,您仍然可以使用.timeStamp
代替new Date()
,只是为了在 正确实施.timeStamp
的浏览器上获得更准确的结果。
http://jsfiddle.net/gagLxrsc是一个小提琴,它通过在事件处理程序中创建mousedown
来计算按钮上mouseup
和new Date()
之间的时间。第一个处理程序在执行此操作后会休眠一秒钟,从而延迟第二个处理程序的触发。在任何浏览器中,计算的点击持续时间大约为一秒(即它将是错误的)。
http://jsfiddle.net/gagLxrsc/1/是小提琴的修改版本。唯一的变化是事件发生的时间是使用事件的.timestamp
属性确定的。在Chrome,Firefox或Safari的现代版本中,这个小提琴准确地计算了点击的持续时间,但在Edge中它仍然是错误的。
答案 2 :(得分:5)
当onmousedown被解雇时,您可以在窗口挂起onmouseup事件。这样可以避免不必要的关闭。
el.onmousedown = function () {
var time = new Date(); //time in milliseconds
window.onmouseup=function(){
var diff=new Date()-time;
window.onmouseup=null;
}
};
在此处查看结果:http://jsbin.com/uneqo
答案 3 :(得分:4)
由于现在其他链接似乎已被破坏,至少在chrome上,这是一个简单的工作演示:
var startTime;
window.startTimer = function() {
startTime = new Date();
}
window.reportTime = function() {
alert(new Date() - startTime)
}
<button onmousedown="startTimer()" onmouseup="reportTime()">Measure click time</button>
答案 4 :(得分:0)
您可以使用两个全局变量来记录mousedown和mouseup的时间,并有一个substract
答案 5 :(得分:0)
我认为这是最优雅的方式:
function onMouseDown(e) {
window.onmouseup = function(e2) {
var diff = e2.timeStamp - e.originalEvent.timeStamp;
console.log(diff);
window.onmouseup = null;
};
}