जावास्क्रिप्ट का उपयोग करते समय एक साथ कई कुंजियों को दबाने पर कैसे पता लगाया जाए?


173

मैं एक जावास्क्रिप्ट गेम इंजन विकसित करने की कोशिश कर रहा हूं और मैं इस समस्या से जूझ रहा हूं:

  • जब मैं SPACEचरित्र को दबाता हूं तो कूद जाता है।
  • जब मैं प्रेस करता हूं तो पात्र सही चलता है।

समस्या यह है कि जब मैं सही दबा रहा होता हूं और फिर स्पेस दबाता हूं, तो चरित्र कूद जाता है और फिर बढ़ना बंद हो जाता है।

मैं keydownकुंजी को दबाने के लिए फ़ंक्शन का उपयोग करता हूं । यदि एक ही बार में कई कुंजी दबाए गए हैं तो मैं कैसे जांच सकता हूं?


3
यहां एक वेब पेज का डेमो दिया गया है जो स्वचालित रूप से दबाए गए सभी कुंजियों की एक सूची प्रिंट करता है: stackoverflow.com/a/13651016/975097
एंडरसन ग्रीन

जवाबों:


327

नोट: कीकोड को अब हटा दिया गया है।

यदि आप अवधारणा को समझें तो मल्टीपल कीस्ट्रोक का पता लगाना आसान है

जिस तरह से मैं यह करता हूं वह इस प्रकार है:

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 */
}

यह कोड बहुत सरल है: चूंकि कंप्यूटर केवल एक बार में एक कीस्ट्रोके से गुजरता है, इसलिए कई कुंजियों का ट्रैक रखने के लिए एक सरणी बनाई जाती है। तब सरणी का उपयोग एक बार में एक या अधिक कुंजियों की जांच के लिए किया जा सकता है।

बस समझाने के लिए, मान लीजिए कि आप प्रेस करते हैं Aऔर B, प्रत्येक keydownउस घटना को आग लगाता है , जो map[e.keyCode]मान के लिए सेट होती है e.type == keydown, जो या तो सही या गलत का मूल्यांकन करती है । अब दोनों map[65]और map[66]पर सेट हैं true। जब आप जाने देते हैं A, तो keyupघटना आग हो जाती है, जिसके कारण map[65](ए) के विपरीत परिणाम का निर्धारण करने के लिए एक ही तर्क होता है, जो अब झूठा है , लेकिन चूंकि map[66](बी) अभी भी "डाउन" है (यह कीप इवेंट को ट्रिगर नहीं किया है) यह सच है

mapसरणी, दोनों घटनाओं के माध्यम से, इस तरह दिखता है:

// keydown A 
// keydown B
[
    65:true,
    66:true
]
// keyup A
// keydown B
[
    65:false,
    66:true
]

अब आप दो काम कर सकते हैं:

ए) एक कुंजी लकड़हारा ( उदाहरण ) बाद में एक संदर्भ के रूप में बनाया जा सकता है जब आप जल्दी से एक या अधिक कुंजी कोड का पता लगाना चाहते हैं। मान लें कि आपने एक 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>

यह एक html तत्व बनाता है जिसे आसानी से जावास्क्रिप्ट में संदर्भित किया जा सकता है element

alert(element); // [Object HTMLDivElement]

तुम भी उपयोग document.getElementById()या $()इसे हड़पने के लिए नहीं है। लेकिन अनुकूलता के लिए, jQuery का उपयोग $()अधिक व्यापक रूप से अनुशंसित है।

बस सुनिश्चित करें कि स्क्रिप्ट टैग HTML के शरीर के बाद आता है। ऑप्टिमाइज़ेशन टिप : अधिकांश बड़ी-नाम वाली वेबसाइट्स ऑप्टिमाइज़ेशन के लिए बॉडी टैग के बाद स्क्रिप्ट टैग लगाती हैं। इसका कारण यह है कि स्क्रिप्ट टैग आगे तत्वों को लोड होने से रोकता है जब तक कि इसकी स्क्रिप्ट डाउनलोड करना समाप्त नहीं हो जाती। इसे सामग्री के आगे रखने से सामग्री पहले से लोड करने की अनुमति मिलती है।

बी (जो आपकी रुचि निहित है) आप एक समय में एक या अधिक कुंजियों की जांच कर सकते /*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');
    }
}

(संपादन का अंत)


यह उदाहरण , और CtrlShiftA, के लिए जाँच करता हैCtrlShiftBCtrlShiftC

यह बिल्कुल उसके जैसा सरल है :)

टिप्पणियाँ

KeyCodes का ट्रैक रखना

एक सामान्य नियम के रूप में, यह दस्तावेज़ कोड के लिए अच्छा अभ्यास है, विशेष रूप से कुंजी कोड (जैसे // CTRL+ENTER) जैसी चीजें ताकि आप याद रख सकें कि वे क्या थे।

आपको दस्तावेज़ीकरण ( CTRL+ENTER => map[17] && map[13], नहीं map[13] && map[17]) के समान कुंजी कोड भी उसी क्रम में रखना चाहिए । इस तरह आप कभी भी भ्रमित नहीं होंगे जब आपको वापस जाकर कोड को संपादित करने की आवश्यकता होगी।

If-चेन के साथ एक गोथा

यदि अलग-अलग मात्रा (जैसे CtrlShiftAltEnterऔर CtrlEnter) के कॉम्ब्स की जांच हो रही है, तो बड़े कॉम्ब्स के बाद छोटे कॉम्बोस डालें , या फिर छोटे कॉम्बोस बड़े कॉम्बोस को ओवरराइड करेंगे यदि वे समान हैं। उदाहरण:

// 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"

गोत्चा: "यह कुंजी कॉम्बो तब भी सक्रिय रहता है जब मैं चाबियाँ दबा नहीं रहा हूं"

अलर्ट या कुछ भी जो मुख्य विंडो से ध्यान केंद्रित करता है, के साथ काम करते समय, आप 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

गोटचा: ब्राउज़र डिफॉल्ट्स

यहाँ एक कष्टप्रद बात मुझे मिली, जिसमें समाधान शामिल है:

समस्या: चूंकि ब्राउज़र में आमतौर पर कुंजी कॉम्बोस पर डिफ़ॉल्ट क्रियाएं होती हैं (जैसे CtrlDबुकमार्क विंडो को सक्रिय करता है, या CtrlShiftCमैक्सथन पर स्किनोट को सक्रिय करता है), तो आप return falseबाद में भी जोड़ना चाह सकते हैं map = [], इसलिए "डुप्लिकेट फ़ाइल" होने पर आपकी साइट के उपयोगकर्ता निराश नहीं होंगे। फ़ंक्शन, पर डाला जा रहा है CtrlD, इसके बजाय पृष्ठ को बुकमार्क करता है।

if(map[17] && map[68]){ // CTRL+D
    alert('The bookmark window didn\'t pop up!');
    map = {};
    return false;
}

बिना return false, बुकमार्क विंडो उपयोगकर्ता के विघटन के लिए पॉप अप होगी

रिटर्न स्टेटमेंट (नया)

ठीक है, इसलिए आप हमेशा उस बिंदु पर फ़ंक्शन से बाहर नहीं निकलना चाहते हैं। इसलिए event.preventDefault()फंक्शन है। यह जो करता है वह एक आंतरिक ध्वज सेट करता है जो दुभाषिया को बताता है ब्राउज़र को अपनी डिफ़ॉल्ट कार्रवाई चलाने की अनुमति नहीं देता है। उसके बाद, फ़ंक्शन का निष्पादन जारी रहता है (जबकि returnतुरंत फ़ंक्शन से बाहर निकल जाएगा)।

उपयोग करने का निर्णय लेने से पहले इस भेद को समझें return false याe.preventDefault()

event.keyCode पदावनत किया गया है

उपयोगकर्ता SeanVieira को उन टिप्पणियों में इंगित किया गया है जो event.keyCodeपदावनत है।

वहां, उन्होंने एक उत्कृष्ट विकल्प दिया: event.keyजो कुंजी के एक स्ट्रिंग प्रतिनिधित्व को दबाता है, जैसे "a"कि A, या"Shift" के लिए 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को लिखना आसान लगता है और इसके बारे में कारण।

भी है 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(मान लें कि यह एक textarea है), और कुंजी कॉम्बो के लिए एक घड़ी सेट करें Ctrl+5। जब दोनों Ctrlऔर 5नीचे होते हैं, तो आपके द्वारा पास किया गया कॉलबैक फ़ंक्शन (इस मामले में, एक फ़ंक्शन जो "FIVE "टेक्सटेरिया में जोड़ता है) कहा जाएगा। कॉलबैक नाम के साथ जुड़ा हुआ है print_5, इसलिए इसे हटाने के लिए, आप बस उपयोग करें:

input_txt.unwatch("print_5");

तत्व input_txtसे अलग करने के लिए txt:

input_txt.detach();

इस तरह, कचरा संग्रह वस्तु को उठा सकता है ( input_txt), इसे फेंक दिया जाना चाहिए, और आपके पास एक पुरानी ज़ोंबी इवेंट श्रोता नहीं होगी।

संपूर्णता के लिए, यहां सी / जावा शैली में प्रस्तुत की गई क्लास की एपीआई का एक त्वरित संदर्भ है, ताकि आप जान सकें कि वे क्या लौटाते हैं और क्या तर्क देते हैं।

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);

Detaches ev_kdownऔर ev_kupपेरेंट तत्व से श्रोताओं, यह संभव बनाने सुरक्षित रूप से उदाहरण से छुटकारा पाने के

अद्यतन 2017/12/02 GitHub को यह प्रकाशित करने के लिए एक अनुरोध के जवाब में, मैं एक बनाया है सार

अपडेट 2018-07-21 मैं थोड़ी देर के लिए घोषणात्मक शैली की प्रोग्रामिंग के साथ खेल रहा हूं, और यह तरीका अब मेरा व्यक्तिगत पसंदीदा है: फिडेल , पास्टबिन

आम तौर पर, यह उन मामलों के साथ काम करेगा जिन्हें आप वास्तविक रूप से चाहते हैं (सीटीएल, एलटी, शिफ्ट), लेकिन अगर आपको हिट करने की आवश्यकता है, तो कहें, a+wउसी समय, ए में दृष्टिकोण को "गठबंधन" करना बहुत मुश्किल नहीं होगा। बहु कुंजी देखने।


मुझे आशा है कि यह पूरी तरह से समझाया गया उत्तर मिनी-ब्लॉग उपयोगी था :)


मैंने इस उत्तर के लिए एक बड़ा अद्यतन किया है! कीगलर का उदाहरण अधिक सुसंगत है, मैंने प्रारूपण को अद्यतन किया ताकि "नोट्स" अनुभाग को पढ़ने में आसान हो, और मैंने return falseबनाम के बारे में एक नया नोट जोड़ाpreventDefault()
ब्रैडेन बेस्ट

जब आप फ़ोकस में दस्तावेज़ के साथ एक कुंजी दबाते / पकड़ते हैं, तब आप URL बॉक्स पर क्लिक करते हैं, तब आप कुंजी को छोड़ देते हैं। कीप को कभी भी निकाल नहीं दिया जाता है, फिर भी कुंजी ऊपर है, जिससे सूची गलत हो जाती है। इसके अलावा इसके विपरीत: URL बॉक्स में कुंजी दबाए रखें / दबाएं, कीडाउन कभी भी बंद नहीं होता है, फिर दस्तावेज़ पर ध्यान केंद्रित करें और कीडाउन की स्थिति सूची में नहीं है। मूल रूप से जब भी दस्तावेज़ फिर से आता है तो आप कभी भी महत्वपूर्ण स्थिति के बारे में सुनिश्चित नहीं हो सकते हैं।
user3015682

3
NB: keyCodeपदावनत किया जाता है - यदि आप स्विच करते हैं keyतो आपको कुंजी का वास्तविक चरित्र प्रतिनिधित्व मिलता है जो अच्छा हो सकता है।
सीन विएरा

1
@ सीनवीरा फिर, आप सी में कुछ अजीब सामान भी कर सकते हैं। उदाहरण के लिए, क्या आप जानते हैं कि myString[5]यह समान है 5[myString], और यह आपको एक संकलित चेतावनी (यहां तक ​​कि -Wall -pedantic) भी नहीं देगा ? ऐसा इसलिए है क्योंकि pointer[offset]अंकन सूचक को लेता है, ऑफसेट जोड़ता है, और फिर परिणाम को dereferences करता है, myString[5]जैसा कि बना रहा है *(myString + 5)
ब्रैडेन बेस्ट

1
@inorganik क्या आप सहायक वर्ग की बात कर रहे हैं? क्या गैस्ट को रिपोज की तरह इस्तेमाल किया जा सकता है? कोड के एक छोटे से स्निपेट के लिए संपूर्ण रेपो बनाना थकाऊ होगा। ज़रूर, मैं एक गिस्ट बनाऊंगा। मैं आज रात के लिए गोली मार दूंगा। मध्यरात्रि पर्वत समय -ish
ब्रैडेन सर्वश्रेष्ठ

30

आप का उपयोग करना चाहिए keydown चाबियों का ट्रैक रखने के लिए दबाया घटना, और आप का उपयोग करना चाहिए KeyUp जब कुंजी जारी कर रहे हैं का ट्रैक रखने के घटना।

इस उदाहरण को देखें: http://jsfiddle.net/vor0nwe/mkHsU/

(अपडेट: मैं यहां कोड को पुन: प्रस्तुत कर रहा हूं, अगर jsfiddle.net बेल्स :) HTML:

<ul id="log">
    <li>List of keys:</li>
</ul>

... और जावास्क्रिप्ट (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 का उपयोग किया है, तो अवधारणा 'कच्चे' जावास्क्रिप्ट में काम करने के साथ ही काम करती है।


लेकिन जैसा कि मैंने सोचा है कि एक बग है। यदि आप एक बटन दबाए रखते हैं, तो बटन दबाते समय बटन दबाए रखते हुए दूसरे टैब (या ढीले फ़ोकस) पर स्विच करें, यह दिखाएगा कि बटन दबाया गया है, भले ही वह न हो। : D
XCS

3
@ क्रिसी: तब आप एक onblurईवेंट हैंडलर भी जोड़ सकते थे , जो एरे से सभी दबाए गए की को हटा देता है। एक बार जब आप फोकस खो देते हैं, तो यह समझ में आता है कि सभी कुंजियों को फिर से दबाया जाए। दुर्भाग्य से, वहाँ कोई जेएस के बराबर है GetKeyboardState
मार्टिज़न

1
एक मैक (क्रोम) पर पेस्ट के साथ एक समस्या है। यह सफलतापूर्वक कीडाउन 91 (कमांड), कीडाउन 86 (वी) प्राप्त करता है, लेकिन फिर केवल कीपेड 91, 86 को नीचे छोड़ देता है। चाबियों की सूची: ऊपर: 91, नीचे: 86. यह केवल तब होता है जब कमांड को दूसरी कुंजी से जाने दिया जाता है - अगर मैं इसे पहले जाने देता हूं तो यह सही ढंग से दोनों पर कीप को पंजीकृत करता है।
जेम्स एल्डे

2
ऐसा प्रतीत होता है कि जब आप एक ही बार में तीन या अधिक कुंजी दबाते हैं, तो जब तक आप एक को उठाते हैं, तब तक किसी भी अधिक कुंजी का पता लगाना बंद कर देता है। (फ़ायरफ़ॉक्स 22 के साथ परीक्षण किया गया)
Qvcool

1
@JamesAlday वही समस्या। यह जाहिरा तौर पर केवल Mac पर मेटा (OS) कुंजी को प्रभावित करता है। यहाँ देखें # 3 अंक: बिट्सप्रुस्डर्निशन
डॉन


7

मैंने इस तरह से उपयोग किया (जहाँ भी जाँच करना है 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;
    }
});

5

जिसके लिए पूर्ण उदाहरण कोड की आवश्यकता है। दाएँ + बाएँ जोड़े गए

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);

3

कीडाउन को भी कई फ़ंक्शन कहते हैं, प्रत्येक फ़ंक्शन के लिए एक विशिष्ट कुंजी की जाँच करें और उचित रूप से जवाब दें।

document.keydown = function (key) {

    checkKey("x");
    checkKey("y");
};

2

मैं एक 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 + Eventपंजीकरण में नहीं)।

कृपया पोस्ट करें कि यह मदद करता है या नहीं।


1
यह काम नहीं करेगा: कीपर बहुत सारी कुंजियों पर ट्रिगर नहीं करता है जो किडाउन और की-अप ट्रिगर करते हैं । साथ ही, सभी ब्राउज़र बार-बार कीडाउन इवेंट को ट्रिगर नहीं करते हैं।
मार्टिन

: Quirksmode अपने गलत कहते हैं quirksmode.org/dom/events/keys.html । लेकिन मैं यह तर्क नहीं दूंगा कि मैंने अपने प्रस्ताव का परीक्षण नहीं किया।
FK82

उस पृष्ठ से उद्धृत: "जब उपयोगकर्ता तीर कुंजी के रूप में विशेष कुंजी दबाता है, तो ब्राउज़र को कीपर घटनाओं को फायर नहीं करना चाहिए" । दोहराव के रूप में, यह ओपेरा और कोनकेर को सही ढंग से नहीं करने के रूप में सूचीबद्ध करता है।
मार्टिअन

2

यदि दबाया गया कोई कुंजी 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()
    }
  }
}

2
    $(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;
            }
        });

    });

आपके योगदान के लिए धन्यवाद। कृपया केवल कोड पोस्ट करने के लिए प्रयास करें, कुछ स्पष्टीकरण जोड़ें।
टिम रटर

2

यह एक सार्वभौमिक तरीका नहीं है, लेकिन यह कुछ मामलों में उपयोगी है। यह की तरह संयोजन के लिए उपयोगी CTRL+ somethingया Shift+ somethingया CTRL+ Shift+ something, आदि

उदाहरण: जब आप CTRL+ का उपयोग करके किसी पृष्ठ को प्रिंट करना चाहते हैं P, तो हमेशा पहली कुंजी को दबाया जाता CTRLहै P। के साथ भी यही CTRL+ S, CTRL+ Uऔर अन्य संयोजन।

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;

        }
    }

});


1
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;

सबसे अच्छा तरीका नहीं है, मुझे पता है।


-1
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);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.