KeyDown不会'按住时不能连续开火
KeyDown doesn't continuously fire when pressed and hold
我有这个Plunkr,
这包含一个div
,我在其上绑定了一个keydown
事件。按下向右或向左箭头时,div应该开始移动。
这在所有浏览器中都有效,但当按键并按住时,第一个keydown事件会立即触发(div一旦移动),它会等待一段时间间隔,然后继续移动。
因此,这意味着keydown
事件被触发一次,然后浏览器等待检测是否也有后续的keyUp
事件,然后在短时间后(当没有keyup时),它继续触发keydown
事件。
(要查看问题,请关注窗口,按下向右箭头并按住,div应移动一次5px,然后等待,然后再次继续移动)
问题:有没有办法,这样我就可以一直按键,div应该立即开始移动,而不需要等待检测到后续的keyup(一次)?
$(function() {
$(window).keydown(function(e) {
console.log(e.keyCode)
if (e.keyCode == 39)
move(5, 'left', $('.mover'))
else if (e.keyCode == 37)
move(-5, 'left', $('.mover'))
})
})
function move(offset, direction, target) {
console.log($(target))
$(target).css(direction, (parseInt($(target).css(direction)) + offset) + 'px')
}
.mover {
height: 50px;
width: 50px;
display: inline-block;
background: black;
position: absolute;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='mover'></div>
我建议在超时时做一些事情,比如这个
http://codepen.io/kevrowe/pen/qEgGVO
$(function() {
var direction,
movingTimeout = -1;
$(window).on('keydown', function(e) {
if (e.keyCode == 39) {
direction = 'right';
} else if (e.keyCode == 37) {
direction = 'left';
}
startMoving(direction);
});
function stopMoving() {
clearTimeout(movingTimeout);
movingTimeout = -1;
}
function startMoving(direction) {
if (movingTimeout === -1) {
loop(direction);
}
}
function loop(direction) {
move(direction === 'left' ? -5 : 5, $('.mover'));
movingTimeout = setTimeout(loop, 10, direction);
}
function move(offset, $target) {
$target.css('left', (parseInt($target.css('left')) + offset) + 'px')
}
$(window).on('keyup', function(e) {
stopMoving();
});
})
当要跟踪的键上发生keydown事件时,将此信息存储在映射或标志中。
当keyup事件发生时,清除给定键的标志。
然后,在计时器上,您可以轮询键映射的状态,并将对象移动到按下的任何键方向。
可能有比轮询更好的解决方案,但除了轮询之外,我不知道还有什么方法可以测试密钥是否坏了。
在设置关键帧时,还需要检查是否需要中断移动对象。
一种解决方案是在循环中连续运行move函数,直到出现键
if (e.keyCode == 39){
var stop = setInterval(function(){
move(5, 'left', $('.mover'))
}, 25);
window.on("keyup", function(){
//stop the loop
clearInterval(stop);
//and remove the keyup listener
window.off("keyup", arguments.callee);
})
} else if //etc...
对于那些可能感兴趣的人,这里有另一种处理双向移动的方法。例如:up
+right
键="东北"方向:
const FPS = 60;
const STEP = 5;
const UP_KEY = 90; // Z
const DOWN_KEY = 83; // S
const LEFT_KEY = 81; // Q
const RIGHT_KEY = 68; // D
const pressedKeys = [];
let movingTimeout = null;
function handleKeyDown(e) {
pressedKeys[e.keyCode] = true;
switch(e.keyCode) {
case DOWN_KEY:
case LEFT_KEY:
case RIGHT_KEY:
case UP_KEY:
e.preventDefault();
startMoving();
}
}
function handleKeyUp(e) {
pressedKeys[e.keyCode] = false;
const shouldStop = !pressedKeys[UP_KEY]
&& !pressedKeys[DOWN_KEY]
&& !pressedKeys[LEFT_KEY]
&& !pressedKeys[RIGHT_KEY]
;
if(shouldStop) {
stopMoving();
}
}
function startMoving() {
if(!movingTimeout){
loop();
}
}
function stopMoving() {
clearTimeout(movingTimeout);
movingTimeout = null;
}
function loop() {
const x = pressedKeys[RIGHT_KEY] ? STEP
: pressedKeys[LEFT_KEY] ? -STEP : 0;
const y = pressedKeys[DOWN_KEY] ? STEP
: pressedKeys[UP_KEY] ? -STEP : 0;
move(x, y);
movingTimeout = setTimeout(loop, 1000 / FPS);
}
function move(x, y) {
// Implement you own logic here for positioning / handling collisions
// Ex: store.dispatch({ type: "MOVE_PLAYER", x, y });
console.log(`Moving ${x} ${y} !`);
}
window.addEventListener('keydown', e => handleKeyDown(e));
window.addEventListener('keyup', e => handleKeyUp(e));
希望这能有所帮助。
干杯!
纯javascript
<input id="some" type="text">
var input=document.getElementById("some");
input.addEventListener("keydown",function(e){
if (e.which == 40) {
var stop = setInterval(function(){
console.log("ss:");
}, 60);
window.addEventListener("keyup", function(){
//stop the loop
clearInterval(stop);
//and remove the keyup listener
window.removeEventListener("keyup", arguments.callee);
})
}
})
相关文章:
- 不能从angular2中的子组件指定父组件中的数组
- AngularJS UI路由器不能像ng路由器那样工作
- HTML5音频加载和播放获胜'我不能在iPad上工作
- 转义符不能与innerHTML一起使用
- JSON.parse没有'不能使用Javascript
- JS可以在Chrome中工作,但不能在Firefox中工作
- 砌体不能填补小缺口
- javascript扫雷器floodfill算法不能正常工作
- JavaScript指令不能像我想象的那样工作
- 为什么在这个网站上不能通过JS访问元素
- Facebook登录按钮没有'不能在Firefox上工作
- WebRTC视频聊天可以在FF中使用,但不能在Chrome中使用
- KeyDown不会'按住时不能连续开火
- 为什么你不能通过连续调用 .text() JQuery 来逃避
- 正则表达式 - 字符串不能以空格开头,以空格结尾,并且连续包含几个空格
- 同一形式的两个素数面板不能通过javascript连续关闭
- jQuery不能正确打开两个连续的模态对话框
- 引导下拉菜单不能连续工作
- RegEx javascript匹配连续出现的2个字符,但不能更多
- 为什么我不能连续增加一个函数中的变量