Javascript 按键时间

标签 javascript jquery timing onkeydown

我正在开发一个对时间非常敏感的应用程序,该应用程序使用按键进行用户输入。因为我在这里说的是毫秒,所以我继续尝试了这样的版本:

function start() {
  //stim.style.display = "block";
  rt_start = new Date().getTime();
  response_allowed = 1;
}

function end() {
  var t = rt_end - rt_start;
  //stim.style.display = "none";
  log.innerHTML = t;
  i++;
  if (i < iterations) {
    setTimeout('start();', 1000);
  }
}

var rt_start;
var rt_end;
var iterations = 100;
var i = 0;
var response_allowed = 0;
var stim;
var log;
$(document).ready(function() {
  document.onkeydown = function(e) {
    if (response_allowed == 1) {
      rt_end = new Date().getTime();
      response_allowed = 0;
      end();
    }
  };
  stim = document.getElementById('stim');
  log = document.getElementById('log');
  start();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="log"></div>
<img src="https://www.gravatar.com/avatar/cfefd93404e6b0eb3cde02b4b6df4e2b?s=128&d=identicon&r=PG&f=1" id="stim" />

而且它工作正常,通常是低于 5 毫秒的计时器(只需按住一个键)。但是一旦我修改代码以显示图像(取消注释这两行),这就会减慢很多,大约 30 毫秒。

有人能告诉我为什么会出现这种情况,以及如何避免这种额外的延迟吗?

谢谢

最佳答案

我建议使用 DOMHighResTimeStamp在可用的地方(对于不提供它的浏览器带有 polyfill)。

这是一个高分辨率时间戳(设计时考虑了精确测量),用于(例如)导航计时和 Web 性能 API(在 Mozilla 开发人员网络中搜索它,因为我不能分享超过两个单个帖子中的链接)。

获取 DOMHighResTimeStamp 的快速方法 - 就像您使用 var ts = new Date().getTime(); 获取常规毫秒时间戳一样 - 是:

var ts = performance.now();

正如我上面所说,看看 MDN 上的 Web Performance API。如果您的应用程序确实对时间很敏感,这将非常有帮助。

编辑:

关于您的代码片段,在我看来,如果您按住某个键,您将始终受限于按键事件的分辨率(持续触发,但不是每毫秒触发一次)。如果您使用文本编辑器按下(连续)字符键并检查该字符每秒被写入多少次,您可以很容易地看到这种行为。。我猜这是通过操作系统设置控制的。

您还受限于与 setTimeout/setInterval 相关的“漂移”。您会看到,setTimeout 会在给定的延迟 后将某事 排入队列以供执行,但它不能保证及时执行。这是一个“尽力而为”的场景,如果浏览器正忙于做某事,它会显着漂移。含义:如果您使用 setTimeout 在 1 秒后重新启用 response_allowed 变量,您可以预期它会在“大约”(但不完全)1 秒后重新启用它。

关于Javascript 按键时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26585171/

相关文章:

javascript - 为什么 window.performance.timing.loadEventStart 是常量?

javascript - AngularJS Timing - 如何让子作用域在 init 上看到父作用域的 $broadcast?

javascript - removeChild 不是函数

javascript - 如何将javascript代码附加到asp.net中的这个动态控件文本框

javascript - 如何访问 nodejs 插件中的包装对象属性

javascript - 为什么我的 jQuery 插件在多个选择器上失败?

jquery - 如何在 TWIG (symfony2) 中使用 JQuery

javascript - jquery 上的 Accordion 。我无法关闭事件元素

javascript - 如何编写一个非阻塞的javascript方法?

python - pygame.time.set_timer 困惑?