Javascript 如何检测何时释放所有钥匙

Javascript 如何检测何时释放所有钥匙,javascript,keyup,Javascript,Keyup,以下代码用于测量一个键(或多个键)被按下的时间 var output=document.getElementById('output'), 按下={}; window.onkeydown=函数(e){ 如果(按下[e])返回; 按下[e]=e.时间戳; }; window.onkeyup=函数(e){ 如果(!按下[e])返回; var duration=(e.timeStamp-按下[e])/1000; var today=新日期(); var date=today.getDate()+'-

以下代码用于测量一个键(或多个键)被按下的时间

var output=document.getElementById('output'),
按下={};
window.onkeydown=函数(e){
如果(按下[e])返回;
按下[e]=e.时间戳;
};
window.onkeyup=函数(e){
如果(!按下[e])返回;
var duration=(e.timeStamp-按下[e])/1000;
var today=新日期();
var date=today.getDate()+'-'+(today.getMonth()+1)+'-'+today.getFullYear();
var time=today.getHours()+“:“+today.getMinutes()+”:“+today.getSeconds();
var dateTime=日期+“”+时间;
output.innerHTML+=dateTime+'-按“+持续时间+”秒的键

”; 按下[e]=0; }

您可以使用另一个值(即
向下)改进您按下的
映射,并在最后检查它

window.onkeydown = function(e) {
    if ( pressed[e.key] ) return;
    pressed[e.key] = {time:e.timeStamp, is_down:true}
};
然后,当发布时,您检查是否有人具有
已关闭:true

window.onkeyup = function(e) {
    if ( !pressed?.is_down ) return;   
    var duration = ( e.timeStamp - pressed[e.key].time ) / 1000;
    var is_all_released = Object.keys(pressed).filter(key => pressed[key].is_down).length > 0
    if (is_all_released) {
        //do your printouts
    }

首先,您应该执行
pressed[e.code]
,而不是
pressed[e]
,因为这个
e
对象值将被字符串化为
[object KeyboardEvent]
,因此您在每个键盘事件上只指定一个相同的属性

要仅在所有按键都已启动时报告,请记录计数和第一个按键按下的时间:

var output=document.getElementById('output'),
按下={},
keyDownCount=0,
keyDownTime=0;
window.onkeydown=函数(e){
如果(按下[e.code])返回;
按下[e.code]=真;
如果(!keyDownCount)keyDownTime=e.时间戳;
keyDownCount++;
};
window.onkeyup=函数(e){
如果(!按下[e.code])返回;
按下[e.code]=false;
按键下载--;
if(keyDownCount)返回;
var持续时间=(例如时间戳-keyDownTime)/1000;
var today=新日期();
var date=today.getDate()+'-'+(today.getMonth()+1)+'-'+today.getFullYear();
var time=today.getHours()+“:“+today.getMinutes()+”:“+today.getSeconds();
变量dateTime=(日期+“”+时间)。替换(/\b\d\b/g,“0$&”);
output.innerHTML+=dateTime+'-按“+持续时间+”秒的键

”; }

要使其正常工作,您需要更改一些内容。 首先,当您在释放所有键后重置缓存的时间戳时,您应该删除该条目,而不仅仅是将时间戳设置为0-这样,下次按下多个键时,您将再次使用空对象重新开始

您可以为此使用
delete
关键字

根据我的理解,你只需要比较第一个时间戳和最后一个时间戳,就可以得到你按键的总时间。因此,我建议您的解决方案是(我也进行了一些重构):

const output=document.getElementById('output');
让按下={};
window.onkeydown=函数(e){
如果(Object.values(pressed).length您可以使用a,然后在最后一个键从集合中移除时执行一些代码(如下面的
onRelease
方法)。要知道持续时间,您还必须跟踪第一个键被按下的时间

下面的示例将逻辑和回调函数移动到
pressed
对象中,但是有很多方法可以进行设置

const output=document.getElementById(“输出”);
功能日志(文本){
const p=document.createElement(“p”);
p、 附加(文本);
输出追加(p);
}
按下常数={
关键字:新集合(),
时间戳:空,
get isEmpty(){return!this.keys.size},
添加(键){
//添加第一个键时保存当前时间戳
如果(this.isEmpty)this.timestamp=Date.now();
返回此.key.add(key);
},
删除(键){
const wasPresent=this.keys.delete(key);
//删除最后一个密钥时触发onRelease
如果(wasPresent&&this.isEmpty)this.onRelease();
有人在场;
},
onRelease(){
const now=新日期();
const duration=now.getTime()-this.timestamp;
log(${now.tolocalString()}-按下${duration}ms`-键);
}
};
document.addEventListener(“keydown”,({code})=>pressed.add(code));
document.addEventListener(“keyup”,({code})=>按下。删除(code));

我不确定,对于没有n键滚动的键盘来说,这是否会变得非常烦人。非常感谢!它就像一个符咒,我注意到你还将日期/时间数字固定为两位数,这看起来好多了!我非常感谢。你介意解释一下“如果(键盘按下计数)”的条件是如何以及为什么的吗在这段代码中工作?我是一个初学者,我完全被这一点弄糊涂了。我认为这与它的功能完全相反。
if(keyDownCount)
if(keyDownCount>0)的缩写
,因为我们知道
keyDownCount
为0或正。因此,如果为正,则仍有按键被按下,我们应该退出该函数,因为没有要报告的内容。类似地,
如果(!keyDownCount)
keyDownCount
为0时,即没有按键时,将为真。因此,这是我们想要记录时间戳的时候,因为我们显然检测到第一个按键被按下。
const output = document.getElementById('output');
let pressed = {};

window.onkeydown = function (e) {
  if (Object.values(pressed).length <= 1) {
    pressed.start = new Date();
  }
  pressed[e.code] = e.timeStamp;
};

window.onkeyup = function (e) {
  delete pressed[e.code];
  const { start, ...rest } = pressed;
  if (rest.length <= 1) {
    const currentTime = new Date();
    const duration = (currentTime - start) / 1000;
    const date = `${currentTime.getDate()}-${currentTime.getMonth() + 1}-${currentTime.getFullYear()}`;
    const time = `${currentTime.getHours()}:${currentTime.getMinutes() + 1}:${currentTime.getSeconds()}`;
    output.innerHTML += `${date} ${time} - Key(s) pressed for ${duration} seconds</p>`;
    delete pressed.start;
  }
};