1、都是监听键盘的行为,但是触发的时机不一样
- onkeydown: 按下任意按键的时候触发的,
onkeydown
触发的时候输入流正要进入系统,也就是说onkeydown
事件一完,输入流就进入了系统,无法改变。所以通过onkeydown
事件可以改变用户是按了哪个键; - onkeypress: 按下并放开任何字母数字键时触发的,
onkeypress
事件是在输入流进入系统后触发的,但输入流暂未被系统处理,此时已经不能改变输入流了; - onkeyup: 抬起按键的时候触发的,可以获取到键值;
onkeyup
则是输入流被系统处理后发生的;
2、长按按键会一直触发keydown事件
这是W3C标准的规范,原始的设计就是这样的,因此长按会导致一直触发;
3、用更流畅的动作来实现如下效果:连续按箭头左键,坦克平滑移动,不出现卡顿
onkeydown + onkeyup + requestAnimation
,长按时,(根据浏览器的刷新频率60Hz,即1000/60=16.7ms),每过16.7ms触发一次onkeydown
事件;
JS代码:
var tankObj = function() {
this.x;
this.y;
this.speed;
this.tankBody = new Image();
this.dir_l;
this.dir_r;
}
tankObj.prototype.init = function() {
this.x = 500;
this.y = 100;
this.speed = 1;
this.tankBody.src = "img/enemy3L.jpg";
this.dir_l = 0;
this.dir_r = 0;
}
tankObj.prototype.drawTank = function() {
if(this.dir_l == 1){
this.x -= this.speed;
if(this.x <= 0) this.x =0;
this.tankBody.src = "img/enemy3R.jpg";
}
if(this.dir_r == 1){
this.x += this.speed;
if(this.x >= 1000) this.x =1000;
this.tankBody.src = "img/enemy3L.jpg";
}
ctx1.drawImage(this.tankBody,this.x,this.y);
}
var tank = new tankObj();
tank.init();
var render = function(){
window.requestAnimationFrame(render);
ctx1.clearRect(0,0,1500,400);
tank.drawTank();
window.onkeydown = function(e){
var e = e || window.event;
if(e.keyCode == 37){
e.preventDefault(); // 拦截滚动条事件
tank.dir_l = 1; // 左箭头
startTime = new Date().valueOf();
}
if(e.keyCode == 39){
e.preventDefault();
tank.dir_r = 1; // 右箭头
}
}
window.onkeyup = function(e){
var e = e || window.event;
if(e.keyCode == 37){
tank.dir_l = 0; // 左箭头
}
if(e.keyCode == 39){
tank.dir_r = 0; // 右箭头
}
}
};
render();