在按键时,运行 一个定时器只有一次 JavaScript
On keydown, run a timer only once with JavaScript
我正在制作一个网页游戏,我想在用户开始游戏时调用一个计时器。基本上,我的做法是当按下其中一个 WASD 键时,启动计时器。问题是,如果您多次敲击按键,它每次都会启动计时器。我只想调用该函数一次。我正在考虑 clearInterval()
,但那会停止计时器。不理想。
这是我的代码。 (下图Fiddlelink)
我认为应该发生的是当按下任何键时,它会首先检查 fired
是否等于 false
。如果是,请将其设置为 true
。然后,如果按下 W、A、S 或 D 键,则启动计时器。
然后当按键恢复时,再次将 fired
设置为 false。
var fired = false;
var timer = document.getElementById("timer");
var playerObj = {
elapsedTime: 0,
startTimer: function () {
setInterval(function () {
playerObj.elapsedTime += 1;
timer.innerHTML = playerObj.elapsedTime;
}, 1000);
}
};
var fired = false;
document.onkeydown = function (e) {
var w = e.keyCode == '87',
a = e.keyCode == '65',
s = e.keyCode == '83',
d = e.keyCode == '68';
if (!fired) {
fired = true;
if (w || a || s || d) {
playerObj.startTimer();
}
}
};
document.onkeyup = function () {
fired = false;
};
我参考了 this question's 答案并尝试使用标志,但它似乎没有用。
我认为您需要更改流程以执行以下操作:
onkeydown
检查 w/a/s/d 标志,然后设置标志并启动计时器
onkeyup
如果不是 w/a/s/d 键,则将标志设置为 false
本质上就是您要在此处执行的操作。我认为这会有所不同,所以当 enter/g/h/etc 被击中时停止。
关键思想是仅当 fired
为 false
时才启动计时器。
如果您希望计时器在每场比赛中启动一次,请在第一个按键事件上将 fired
设置为 true
并启动计时器。在随后的按键事件中,检查 fired
的值并拒绝启动计时器。
var fired = false;
var timer = document.getElementById("timer");
var playerObj = {
elapsedTime: -1,
update: function () {
playerObj.elapsedTime += 1;
timer.innerHTML = playerObj.elapsedTime;
},
startTimer: function () {
playerObj.update();
setInterval(playerObj.update, 1000);
}
};
document.onkeydown = function (e) {
var w = e.keyCode == '87',
a = e.keyCode == '65',
s = e.keyCode == '83',
d = e.keyCode == '68';
if (!fired) {
fired = true;
if (w || a || s || d) {
playerObj.startTimer();
}
}
};
#timer {
font-family: sans-serif;
font-size: 24px;
color: #444;
border: 1px solid #ddd;
display: inline-block;
padding: 5px 15px;
}
<div id="timer">-</div>
另一种方法是在第一个按键事件之后替换按键处理程序。
var fired = false;
var timer = document.getElementById("timer");
var playerObj = {
elapsedTime: -1,
update: function () {
playerObj.elapsedTime += 1;
timer.innerHTML = playerObj.elapsedTime;
},
startTimer: function () {
playerObj.update();
setInterval(playerObj.update, 1000);
}
};
var keyToString = {
87: '↑',
65: '←',
83: '↓',
68: '→'
};
function keyHandler(event) { // Handles all valid keys.
var display = document.getElementById('display');
display.innerHTML = keyToString[event.keyCode];
}
document.onkeydown = function (event) { // Handles the first valid key.
if (keyToString[event.keyCode] !== undefined) {
playerObj.startTimer(); // Start the timer.
document.onkeydown = keyHandler; // Replace this key handler.
keyHandler(event); // Call the general key handler.
}
};
#timer, #display {
font-family: sans-serif;
font-size: 24px;
color: #444;
padding: 5px 15px;
}
#timer {
display: inline-block;
border: 1px solid #ddd;
}
<div id="timer">-</div>
<div id="display"></div>
问题有点不清楚,所以这可能没有抓住重点。每点击一次 WASD 就会启动一次计时器。
var timer = document.getElementById("timer");
var playerObj = {
elapsedTime: 0,
startTimer: function () {
setInterval(function () {
playerObj.elapsedTime += 1;
timer.innerHTML = playerObj.elapsedTime;
}, 1000);
}
};
// keep track of keys indiividually
var keyPressed = {
w: false,
a: false,
s: false,
d: false
};
// make it easy to translate keyCodes to key names
var CODES = {
87: 'w',
65: 'a',
83: 's',
68: 'd'
};
document.onkeydown = function (e) {
// look up the key
var keyName = CODES[e.keyCode];
// if it's one we're interested in and it hasn't been pressed yet
if (keyName && !keyPressed[keyName]) {
playerObj.startTimer();
// mark it as having been pressed
keyPressed[keyName] = true;
}
};
为此你根本不需要标志,你所要做的就是在计时器启动后将事件侦听器设置为 null
,然后此函数将永远不会再次 运行。它比此处的其他解决方案更好,因为您不希望此功能 运行ning 可能会阻止 UI.
中的其他事件
document.onkeydown = function (e) {
var w = e.keyCode == '87',
a = e.keyCode == '65',
s = e.keyCode == '83',
d = e.keyCode == '68';
if (w || a || s || d) {
playerObj.startTimer();
document.onkeydown = null;
}
};
我正在制作一个网页游戏,我想在用户开始游戏时调用一个计时器。基本上,我的做法是当按下其中一个 WASD 键时,启动计时器。问题是,如果您多次敲击按键,它每次都会启动计时器。我只想调用该函数一次。我正在考虑 clearInterval()
,但那会停止计时器。不理想。
这是我的代码。 (下图Fiddlelink)
我认为应该发生的是当按下任何键时,它会首先检查 fired
是否等于 false
。如果是,请将其设置为 true
。然后,如果按下 W、A、S 或 D 键,则启动计时器。
然后当按键恢复时,再次将 fired
设置为 false。
var fired = false;
var timer = document.getElementById("timer");
var playerObj = {
elapsedTime: 0,
startTimer: function () {
setInterval(function () {
playerObj.elapsedTime += 1;
timer.innerHTML = playerObj.elapsedTime;
}, 1000);
}
};
var fired = false;
document.onkeydown = function (e) {
var w = e.keyCode == '87',
a = e.keyCode == '65',
s = e.keyCode == '83',
d = e.keyCode == '68';
if (!fired) {
fired = true;
if (w || a || s || d) {
playerObj.startTimer();
}
}
};
document.onkeyup = function () {
fired = false;
};
我参考了 this question's 答案并尝试使用标志,但它似乎没有用。
我认为您需要更改流程以执行以下操作:
onkeydown 检查 w/a/s/d 标志,然后设置标志并启动计时器
onkeyup 如果不是 w/a/s/d 键,则将标志设置为 false
本质上就是您要在此处执行的操作。我认为这会有所不同,所以当 enter/g/h/etc 被击中时停止。
关键思想是仅当 fired
为 false
时才启动计时器。
如果您希望计时器在每场比赛中启动一次,请在第一个按键事件上将 fired
设置为 true
并启动计时器。在随后的按键事件中,检查 fired
的值并拒绝启动计时器。
var fired = false;
var timer = document.getElementById("timer");
var playerObj = {
elapsedTime: -1,
update: function () {
playerObj.elapsedTime += 1;
timer.innerHTML = playerObj.elapsedTime;
},
startTimer: function () {
playerObj.update();
setInterval(playerObj.update, 1000);
}
};
document.onkeydown = function (e) {
var w = e.keyCode == '87',
a = e.keyCode == '65',
s = e.keyCode == '83',
d = e.keyCode == '68';
if (!fired) {
fired = true;
if (w || a || s || d) {
playerObj.startTimer();
}
}
};
#timer {
font-family: sans-serif;
font-size: 24px;
color: #444;
border: 1px solid #ddd;
display: inline-block;
padding: 5px 15px;
}
<div id="timer">-</div>
另一种方法是在第一个按键事件之后替换按键处理程序。
var fired = false;
var timer = document.getElementById("timer");
var playerObj = {
elapsedTime: -1,
update: function () {
playerObj.elapsedTime += 1;
timer.innerHTML = playerObj.elapsedTime;
},
startTimer: function () {
playerObj.update();
setInterval(playerObj.update, 1000);
}
};
var keyToString = {
87: '↑',
65: '←',
83: '↓',
68: '→'
};
function keyHandler(event) { // Handles all valid keys.
var display = document.getElementById('display');
display.innerHTML = keyToString[event.keyCode];
}
document.onkeydown = function (event) { // Handles the first valid key.
if (keyToString[event.keyCode] !== undefined) {
playerObj.startTimer(); // Start the timer.
document.onkeydown = keyHandler; // Replace this key handler.
keyHandler(event); // Call the general key handler.
}
};
#timer, #display {
font-family: sans-serif;
font-size: 24px;
color: #444;
padding: 5px 15px;
}
#timer {
display: inline-block;
border: 1px solid #ddd;
}
<div id="timer">-</div>
<div id="display"></div>
问题有点不清楚,所以这可能没有抓住重点。每点击一次 WASD 就会启动一次计时器。
var timer = document.getElementById("timer");
var playerObj = {
elapsedTime: 0,
startTimer: function () {
setInterval(function () {
playerObj.elapsedTime += 1;
timer.innerHTML = playerObj.elapsedTime;
}, 1000);
}
};
// keep track of keys indiividually
var keyPressed = {
w: false,
a: false,
s: false,
d: false
};
// make it easy to translate keyCodes to key names
var CODES = {
87: 'w',
65: 'a',
83: 's',
68: 'd'
};
document.onkeydown = function (e) {
// look up the key
var keyName = CODES[e.keyCode];
// if it's one we're interested in and it hasn't been pressed yet
if (keyName && !keyPressed[keyName]) {
playerObj.startTimer();
// mark it as having been pressed
keyPressed[keyName] = true;
}
};
为此你根本不需要标志,你所要做的就是在计时器启动后将事件侦听器设置为 null
,然后此函数将永远不会再次 运行。它比此处的其他解决方案更好,因为您不希望此功能 运行ning 可能会阻止 UI.
document.onkeydown = function (e) {
var w = e.keyCode == '87',
a = e.keyCode == '65',
s = e.keyCode == '83',
d = e.keyCode == '68';
if (w || a || s || d) {
playerObj.startTimer();
document.onkeydown = null;
}
};