JavaScript를 사용하여 여러 키를 동시에 눌렀는지 어떻게 검출합니까?
JavaScript 게임 엔진을 개발하려고 하는데 이 문제를 발견했습니다.
- 내가 누르면 캐릭터가 점프해.
- 누르면 캐릭터가 오른쪽으로 이동합니다.
문제는 오른쪽을 누른 후 공간을 누르면 캐릭터가 점프하여 움직임을 멈춘다는 것입니다.
용 the the the를 .keydown
키를 누르는 기능을 수행합니다.한 번에 여러 개의 키가 눌려 있는지 확인하려면 어떻게 해야 하나요?
주의: keyCode는 폐지되었습니다.
개념을 이해하면 여러 키 입력 검출이 용이합니다.
제가 하는 방법은 다음과 같습니다.
var map = {}; // You could also use an array
onkeydown = onkeyup = function(e){
e = e || event; // to deal with IE
map[e.keyCode] = e.type == 'keydown';
/* insert conditional here */
}
이 코드는 매우 간단합니다.컴퓨터는 한 번에 하나의 키 입력만 통과하므로 여러 키를 추적하기 위해 배열이 생성됩니다.그런 다음 어레이를 사용하여 한 번에 하나 이상의 키를 확인할 수 있습니다.
설명하자면, 를 누른다고 가정해 보겠습니다.각각은 1초당 1초당 1초당 1초당 1초씩keydown
를 설정하는 map[e.keyCode]
e.type == keydown
true 또는 false 중 하나로 평가됩니다.이제 둘 다map[65]
★★★★★★★★★★★★★★★★★」map[66]
로 설정되어 있다.true
★★★★★★★★★★★★★★★★★★★★★★를 놓으면,A
, . . . . . . . .keyup
에서는, 이 「이벤트 기동」에 반대의 를 판별합니다.map[65]
(A) 지금은 거짓이지만,map[66]
(B)는 여전히 "down"(키업 이벤트를 트리거하지 않음)이며 true로 유지됩니다.
map
현상을 다음과.
// keydown A
// keydown B
[
65:true,
66:true
]
// keyup A
// keydown B
[
65:false,
66:true
]
다음 두 가지 작업을 수행할 수 있습니다.
A) 키 로거(예)는 나중에 하나 이상의 키 코드를 빠르게 파악하고 싶을 때 참조할 수 있도록 작성할 수 있습니다.html 요소를 정의하고 변수와 함께 지정했다고 가정합니다.element
.
element.innerHTML = '';
var i, l = map.length;
for(i = 0; i < l; i ++){
if(map[i]){
element.innerHTML += '<hr>' + i;
}
}
주의: 요소를 쉽게 잡을 수 있습니다.id
여하하다
<div id="element"></div>
참조할 수 됩니다.element
alert(element); // [Object HTMLDivElement]
.document.getElementById()
★★★★★★★★★★★★★★★★★」$()
jQuery를 사용합니다.$()
보다 폭넓게 권장됩니다.
스크립트 태그가 HTML 본문 뒤에 있는지 확인하세요.최적화 힌트:대부분의 유명 웹사이트는 최적화를 위해 본문 태그 뒤에 스크립트 태그를 붙입니다.스크립트 태그는 스크립트 다운로드가 완료될 때까지 추가 요소의 로드를 차단하기 때문입니다.컨텐츠보다 앞에 두면, 컨텐츠를 사전에 로드할 수 있습니다.
B(관심이 있는 위치) 한 번에 하나 이상의 키를 확인할 수 있습니다./*insert conditional here*/
예를 들어 다음과 같습니다.
if(map[17] && map[16] && map[65]){ // CTRL+SHIFT+A
alert('Control Shift A');
}else if(map[17] && map[16] && map[66]){ // CTRL+SHIFT+B
alert('Control Shift B');
}else if(map[17] && map[16] && map[67]){ // CTRL+SHIFT+C
alert('Control Shift C');
}
편집: 가장 읽기 쉬운 토막이 아닙니다.가독성이 중요하기 때문에 다음과 같은 기능을 사용하여 쉽게 볼 수 있습니다.
function test_key(selkey){
var alias = {
"ctrl": 17,
"shift": 16,
"A": 65,
/* ... */
};
return key[selkey] || key[alias[selkey]];
}
function test_keys(){
var keylist = arguments;
for(var i = 0; i < keylist.length; i++)
if(!test_key(keylist[i]))
return false;
return true;
}
사용방법:
test_keys(13, 16, 65)
test_keys('ctrl', 'shift', 'A')
test_key(65)
test_key('A')
이게 나아요?
if(test_keys('ctrl', 'shift')){
if(test_key('A')){
alert('Control Shift A');
} else if(test_key('B')){
alert('Control Shift B');
} else if(test_key('C')){
alert('Control Shift C');
}
}
(편집 종료)
이 예에서는 , 및 을 확인합니다.
이것은 매우 간단합니다:)
메모들
키 코드 추적
.특히 키 코드(「」, 「」등)를해 주세요. // CTRL+ENTER
)을(를) 기억하실 수 있습니다.
.CTRL+ENTER => map[17] && map[13]
.map[13] && map[17]
이렇게 하면 코드를 다시 편집해야 할 때 혼란이 생기지 않습니다.
if-else 체인이 달린 gotcha
다른 양의 콤보(및 등)를 체크할 경우 큰 콤보 뒤에 작은 콤보를 넣습니다.그렇지 않으면 작은 콤보가 큰 콤보보다 우선합니다.예:
// Correct:
if(map[17] && map[16] && map[13]){ // CTRL+SHIFT+ENTER
alert('Whoa, mr. power user');
}else if(map[17] && map[13]){ // CTRL+ENTER
alert('You found me');
}else if(map[13]){ // ENTER
alert('You pressed Enter. You win the prize!')
}
// Incorrect:
if(map[17] && map[13]){ // CTRL+ENTER
alert('You found me');
}else if(map[17] && map[16] && map[13]){ // CTRL+SHIFT+ENTER
alert('Whoa, mr. power user');
}else if(map[13]){ // ENTER
alert('You pressed Enter. You win the prize!');
}
// What will go wrong: When trying to do CTRL+SHIFT+ENTER, it will
// detect CTRL+ENTER first, and override CTRL+SHIFT+ENTER.
// Removing the else's is not a proper solution, either
// as it will cause it to alert BOTH "Mr. Power user" AND "You Found Me"
Gotcha: "키를 누르지 않아도 이 키 조합이 계속 활성화됩니다."
메인창에서 는 '경보'나 '경보'를 할 수 .map = []
이치노왜냐하면 어떤 일들은...alert()
기본 창에서 포커스를 떼고 '키업' 이벤트가 트리거되지 않도록 합니다.예를 들어 다음과 같습니다.
if(map[17] && map[13]){ // CTRL+ENTER
alert('Oh noes, a bug!');
}
// When you Press any key after executing this, it will alert again, even though you
// are clearly NOT pressing CTRL+ENTER
// The fix would look like this:
if(map[17] && map[13]){ // CTRL+ENTER
alert('Take that, bug!');
map = {};
}
// The bug no longer happens since the array is cleared
Gotcha: 브라우저 기본값
다음은 솔루션과 함께 발견한 성가신 내용입니다.
문제:브라우저에는 보통 키 조합에 대한 기본 작업(북마크 창 활성화 또는 maxthon에서 skynote 활성화 등)이 있으므로 추가하기를 원할 수도 있습니다.return false
후에map = []
따라서 사이트 사용자는 "Duplicate File(파일 복제)" 기능을 on으로 하여 페이지를 북마크해도 당황하지 않습니다.
if(map[17] && map[68]){ // CTRL+D
alert('The bookmark window didn\'t pop up!');
map = {};
return false;
}
return false
[ Bookmark ](북마크)창이 팝업 되어 사용자를 실망시킵니다.
반품명세서(신규)
그 시점에서 항상 기능을 종료하고 싶은 것은 아닙니다.그 that가event.preventDefault()
기능이 있습니다.브라우저가 기본 액션을 실행하지 않도록 인터프리터에 지시하는 내부 플래그를 설정합니다.그 후 함수의 실행은 계속됩니다(여기에 따라).return
을 이용하다
한 후 사용 하십시오.return false
★★★★★★★★★★★★★★★★★」e.preventDefault()
event.keyCode
되지 않습니다.
사용자 SeanVieira는 댓글에서 다음과 같이 지적했다.event.keyCode
을 사용하다
했습니다: 거기, ,, there there there there there there there there there there there there there there there there there there there there there 。event.key
키의 문자열 를 들어, 「키」는 「키」는 「키」입니다."a"
의 경우"Shift"
용으로 설정합니다.
나는 그 현을 검사하기 위한 도구를 만들어 냈다.
element.onevent
»element.addEventListener
된 핸들러addEventListener
쌓을 수 등록 할 수 ..onevent
직접적으로는 공격적이고 이전에 가졌던 모든 것을 무시합니다.
document.body.onkeydown = function(ev){
// do some stuff
ev.preventDefault(); // cancels default actions
return false; // cancels this function as well as default actions
}
document.body.addEventListener("keydown", function(ev){
// do some stuff
ev.preventDefault() // cancels default actions
return false; // cancels this function only
});
.onevent
이 모든 것및 것 .ev.preventDefault()
★★★★★★★★★★★★★★★★★」return false;
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
경우든, 는 「」를 시켜 주세요.addEventlistener
더더 、 론론론론론것 。
, there있있 there 도 있다.attachEvent("onevent", callback)
그러나 이는 폐지된 것을 넘어 자바스크립트(JScript라고 하는 난해한 언어와 관련되지도 않습니다).가능한 한 폴리글롯 코드를 사용하지 않는 것이 가장 좋습니다.
도우미 클래스
혼란/불만에 대처하기 위해 다음 추상화(pastebin 링크)를 수행하는 "클래스"를 작성했습니다.
function Input(el){
var parent = el,
map = {},
intervals = {};
function ev_kdown(ev)
{
map[ev.key] = true;
ev.preventDefault();
return;
}
function ev_kup(ev)
{
map[ev.key] = false;
ev.preventDefault();
return;
}
function key_down(key)
{
return map[key];
}
function keys_down_array(array)
{
for(var i = 0; i < array.length; i++)
if(!key_down(array[i]))
return false;
return true;
}
function keys_down_arguments()
{
return keys_down_array(Array.from(arguments));
}
function clear()
{
map = {};
}
function watch_loop(keylist, callback)
{
return function(){
if(keys_down_array(keylist))
callback();
}
}
function watch(name, callback)
{
var keylist = Array.from(arguments).splice(2);
intervals[name] = setInterval(watch_loop(keylist, callback), 1000/24);
}
function unwatch(name)
{
clearInterval(intervals[name]);
delete intervals[name];
}
function detach()
{
parent.removeEventListener("keydown", ev_kdown);
parent.removeEventListener("keyup", ev_kup);
}
function attach()
{
parent.addEventListener("keydown", ev_kdown);
parent.addEventListener("keyup", ev_kup);
}
function Input()
{
attach();
return {
key_down: key_down,
keys_down: keys_down_arguments,
watch: watch,
unwatch: unwatch,
clear: clear,
detach: detach
};
}
return Input();
}
이 클래스는 모든 것을 할 수 있는 것은 아니며 생각할 수 있는 모든 사용 사례를 처리할 수 있는 것도 아닙니다.난 도서관 사람이 아니야하지만 일반적인 대화형 사용이라면 괜찮을 것입니다.
이 클래스를 사용하려면 인스턴스를 만들고 키보드 입력을 관련짓는 요소를 가리킵니다.
var input_txt = Input(document.getElementById("txt"));
input_txt.watch("print_5", function(){
txt.value += "FIVE ";
}, "Control", "5");
됩니다.#txt
키 콤보(키 콤보)의합니다.Ctrl+5
둘 다 할 때Ctrl
★★★★★★★★★★★★★★★★★」5
이 경우는, 「콜백」의 기능을 추가하는 )입니다."FIVE "
텍스트 영역까지)가 호출됩니다. ""에 .print_5
, , , , , , , , , , , , , , , , , , , , , , , , ,, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
input_txt.unwatch("print_5");
input_txt
txt
★★★★
input_txt.detach();
하면 가비지 컬렉션」)를 할 수 .input_txt
버리면 오래된 좀비 이벤트 청취자가 남지 않습니다.
C/Java 스타일로 제공되는 클래스의 API에 대한 간단한 참조를 통해 반환되는 항목과 예상되는 인수를 알 수 있습니다.
Boolean key_down (String key);
true
key
거짓Boolean keys_down (String key1, String key2, ...);
true
키를 누르면key1 .. keyN
거짓void watch (String name, Function callback, String key1, String key2, ...);
'감시 포인트'를 포인트.
keyN
.void unwatch (String name);
해당 이름을 사용하여 해당 감시점을 제거합니다.
void clear (void);
「키 다운」캐시를 소거합니다.가가에
map = {}
void detach (void);
.
ev_kdown
★★★★★★★★★★★★★★★★★」ev_kup
할 수 .
업데이트 2017-12-02 GITHUB에 게시해달라는 요청에 따라 GIST를 작성하였습니다.
업데이트 2018-07-21 한동안 선언형 프로그래밍을 사용했는데, 지금은 이 방법이 제가 개인적으로 가장 좋아하는 방법입니다: findle, pastebin
경우 shift)와함께 할 수 , , alt, shift)를 쳐야 ctrl, alt, shift를 쳐야 할 에는 ctrl, alt, shift를 합니다.a+w
동시에 접근 방식을 다중 키 모음으로 "수정"하는 것은 그리 어렵지 않습니다.
답변 미니 블로그가 도움이 되었기를 바랍니다:)
document.onkeydown = keydown;
function keydown (evt) {
if (!evt) evt = event;
if (evt.ctrlKey && evt.altKey && evt.keyCode === 115) {
alert("CTRL+ALT+F4");
} else if (evt.shiftKey && evt.keyCode === 9) {
alert("Shift+TAB");
}
}
키 다운 이벤트를 사용하여 누른 키를 추적하고 키 업 이벤트를 사용하여 키가 언제 해제되었는지 추적해야 합니다.
다음의 예를 참조해 주세요.http://jsfiddle.net/vor0nwe/mkHsU/
(갱신:jsfiddle.net가 실패할 경우를 대비해서 여기서 코드를 재생하고 있습니다.HTML:
<ul id="log">
<li>List of keys:</li>
</ul>
...그리고 Javascript(jQuery 사용):
var log = $('#log')[0],
pressedKeys = [];
$(document.body).keydown(function (evt) {
var li = pressedKeys[evt.keyCode];
if (!li) {
li = log.appendChild(document.createElement('li'));
pressedKeys[evt.keyCode] = li;
}
$(li).text('Down: ' + evt.keyCode);
$(li).removeClass('key-up');
});
$(document.body).keyup(function (evt) {
var li = pressedKeys[evt.keyCode];
if (!li) {
li = log.appendChild(document.createElement('li'));
}
$(li).text('Up: ' + evt.keyCode);
$(li).addClass('key-up');
});
이 예에서는 어레이를 사용하여 누르고 있는 키를 추적하고 있습니다.에서는 「」라고 하는 .delete
각 요소의 관련 키가 해방되면, 각 요소에 액세스 할 수 있습니다.
이 예에서는 jQuery를 사용하여 작업을 쉽게 수행했지만, 이 개념은 'raw' Javascript에서 작업할 때도 동일하게 작동합니다.
완전한 예제 코드가 필요한 사용자를 위해.오른쪽+왼쪽 추가
var keyPressed = {};
document.addEventListener('keydown', function(e) {
keyPressed[e.key + e.location] = true;
if(keyPressed.Shift1 == true && keyPressed.Control1 == true){
// Left shift+CONTROL pressed!
keyPressed = {}; // reset key map
}
if(keyPressed.Shift2 == true && keyPressed.Control2 == true){
// Right shift+CONTROL pressed!
keyPressed = {};
}
}, false);
document.addEventListener('keyup', function(e) {
keyPressed[e.key + e.location] = false;
keyPressed = {};
}, false);
이 방법을 사용했습니다(Shift + Ctrl 키를 누른 위치를 확인해야 함).
// create some object to save all pressed keys
var keys = {
shift: false,
ctrl: false
};
$(document.body).keydown(function(event) {
// save status of the button 'pressed' == 'true'
if (event.keyCode == 16) {
keys["shift"] = true;
} else if (event.keyCode == 17) {
keys["ctrl"] = true;
}
if (keys["shift"] && keys["ctrl"]) {
$("#convert").trigger("click"); // or do anything else
}
});
$(document.body).keyup(function(event) {
// reset status of the button 'released' == 'false'
if (event.keyCode == 16) {
keys["shift"] = false;
} else if (event.keyCode == 17) {
keys["ctrl"] = false;
}
});
이것은 일반적인 방법은 아니지만 경우에 따라서는 쓸모가 있습니다.+, +, +, + 등의 조합에 매우 적합합니다.
예:+ 를 사용해 페이지를 인쇄하는 경우는, 최초로 누르는 키가 항상 뒤에 이어집니다.+ , + 및 그 외의 조합에서도 마찬가지입니다.
document.addEventListener('keydown',function(e){
//SHIFT + something
if(e.shiftKey){
switch(e.code){
case 'KeyS':
console.log('Shift + S');
break;
}
}
//CTRL + SHIFT + something
if(e.ctrlKey && e.shiftKey){
switch(e.code){
case 'KeyS':
console.log('CTRL + Shift + S');
break;
}
}
});
게임 입력 스크립트를 작성할 때 매우 유용한 스니펫을 사용하고 싶습니다.
var keyMap = [];
window.addEventListener('keydown', (e)=>{
if(!keyMap.includes(e.keyCode)){
keyMap.push(e.keyCode);
}
})
window.addEventListener('keyup', (e)=>{
if(keyMap.includes(e.keyCode)){
keyMap.splice(keyMap.indexOf(e.keyCode), 1);
}
})
function key(x){
return (keyMap.includes(x));
}
function checkGameKeys(){
if(key(32)){
// Space Key
}
if(key(37)){
// Left Arrow Key
}
if(key(39)){
// Right Arrow Key
}
if(key(38)){
// Up Arrow Key
}
if(key(40)){
// Down Arrow Key
}
if(key(65)){
// A Key
}
if(key(68)){
// D Key
}
if(key(87)){
// W Key
}
if(key(83)){
// S Key
}
}
각 기능이 특정 키를 확인하고 적절하게 응답하는 여러 함수를 호출하는 키다운을 만듭니다.
document.keydown = function (key) {
checkKey("x");
checkKey("y");
};
$(document).ready(function () {
// using ascii 17 for ctrl, 18 for alt and 83 for "S"
// ctr+alt+S
var map = { 17: false, 18: false, 83: false };
$(document).keyup(function (e) {
if (e.keyCode in map) {
map[e.keyCode] = true;
if (map[17] && map[18] && map[83]) {
// Write your own code here, what you want to do
map[17] = false;
map[18] = false;
map[83] = false;
}
}
else {
// if u press any other key apart from that "map" will reset.
map[17] = false;
map[18] = false;
map[83] = false;
}
});
});
여기 브래든스의 답변이 있습니다.
var keys = {}
function handleKeyPress(evt) {
let { keyCode, type } = evt || Event; // to deal with IE
let isKeyDown = (type == 'keydown');
keys[keyCode] = isKeyDown;
// test: enter key is pressed down & shift isn't currently being pressed down
if(isKeyDown && keys[13] && !keys[16]){
console.log('user pressed enter without shift')
}
};
window.addEventListener("keyup", handleKeyPress);
window.addEventListener("keydown", handleKeyPress);
저도 한번 keypress
Event
keydown
window.onkeydown = function() {
// evaluate key and call respective handler
window.onkeypress = function() {
// evaluate key and call respective handler
}
}
window.onkeyup = function() {
window.onkeypress = void(0) ;
}
하기 위한 하지 않습니다( 브라우저 고유의 2+는 ).여기서는 자세히 설명하지 않겠습니다(특히 브라우저 고유의 레벨 2+는 설명하지 않습니다).Event
★★★★★★★★★★★★★★★★★★」
도움이 되든 안 되든 다시 올려주세요.
누른 키 중 하나가 Alt / Crtl / Shift인 경우 다음 방법을 사용할 수 있습니다.
document.body.addEventListener('keydown', keysDown(actions) );
function actions() {
// do stuff here
}
// simultaneous pressing Alt + R
function keysDown (cb) {
return function (zEvent) {
if (zEvent.altKey && zEvent.code === "KeyR" ) {
return cb()
}
}
}
case 65: //A
jp = 1;
setTimeout("jp = 0;", 100);
if(pj > 0) {
ABFunction();
pj = 0;
}
break;
case 66: //B
pj = 1;
setTimeout("pj = 0;", 100);
if(jp > 0) {
ABFunction();
jp = 0;
}
break;
최선의 방법은 아닌 거 알아.
좀 더 안정적인 것을 만드는 것 뿐:
var keys = [];
$(document).keydown(function (e) {
if(e.which == 32 || e.which == 70){
keys.push(e.which);
if(keys.length == 2 && keys.indexOf(32) != -1 && keys.indexOf(70) != -1){
alert("it WORKS !!"); //MAKE SOMETHING HERE---------------->
keys.length = 0;
}else if((keys.indexOf(32) == -1 && keys.indexOf(70) != -1) || (keys.indexOf(32) != -1 && keys.indexOf(70) == -1) && (keys.indexOf(32) > 1 || keys.indexOf(70) > 1)){
}else{
keys.length = 0;
}
}else{
keys.length = 0;
}
});
컨트롤 키로 키 누르기 이벤트를 찾으려면 다음과 같이 하십시오.
onkeypress = (e) =>{
console.log(e);
if(e.ctrlKey && e.code == "KeyZ"){
document.write("do somthing")
} }
Easiest, and most Effective Method
//check key press
function loop(){
//>>key<< can be any string representing a letter eg: "a", "b", "ctrl",
if(map[*key*]==true){
//do something
}
//multiple keys
if(map["x"]==true&&map["ctrl"]==true){
console.log("x, and ctrl are being held down together")
}
}
//>>>variable which will hold all key information<<
var map={}
//Key Event Listeners
window.addEventListener("keydown", btnd, true);
window.addEventListener("keyup", btnu, true);
//Handle button down
function btnd(e) {
map[e.key] = true;
}
//Handle Button up
function btnu(e) {
map[e.key] = false;
}
//>>>If you want to see the state of every Key on the Keybaord<<<
setInterval(() => {
for (var x in map) {
log += "|" + x + "=" + map[x];
}
console.log(log);
log = "";
}, 300);
언급URL : https://stackoverflow.com/questions/5203407/how-to-detect-if-multiple-keys-are-pressed-at-once-using-javascript
'programing' 카테고리의 다른 글
ISO 8601 형식의 날짜를 해석하려면 어떻게 해야 합니까? (0) | 2022.09.22 |
---|---|
AngularJS 1.2$injector: 모듈러 (0) | 2022.09.22 |
int[] 어레이와 int 어레이의 차이[] (0) | 2022.09.15 |
sql-mode=를 만드는 방법"MySQL my.cnf에서 NO_ENGINE_SUBTITION" 영속적 (0) | 2022.09.15 |
연관지을 수 있는 어레이에서 키와 그 값을 삭제하려면 어떻게 해야 합니까? (0) | 2022.09.15 |