जांचें कि क्या कोई कुंजी नीचे है?


91

क्या यह पता लगाने का कोई तरीका है कि वर्तमान में कोई कुंजी जावास्क्रिप्ट में है या नहीं?

मैं "कीडाउन" इवेंट के बारे में जानता हूं, लेकिन मुझे इसकी आवश्यकता नहीं है। कुछ समय के बाद कुंजी को दबाया जाता है, मैं यह पता लगाने में सक्षम होना चाहता हूं कि क्या यह अभी भी दबाया गया है।

PS सबसे बड़ा मुद्दा यह प्रतीत होता है कि कुछ समय के बाद कुंजी दोहराना शुरू कर देती है, कीडाउन और कीप इवेंट्स को फायर करना बंद कर देता है। उम्मीद है कि बस एक साधारण isKeyDown (कुंजी) फ़ंक्शन है, लेकिन यदि नहीं तो इस मुद्दे को दूर करने / चारों ओर काम करने की आवश्यकता होगी।


6
मेरे द्वारा देखे जाने वाले उत्तरों के साथ एक सामान्य समस्या यह है कि यदि आप एक कुंजी दबाए रखते हैं, तो टैब बदलें या फ़ोकस बदलें, कुंजी को छोड़ दें, और फिर वापस स्विच करें, कोड विश्वास करेगा कि कुंजी तब तक नीचे है जब तक आप इसे फिर से दबाते हैं या स्थानांतरित नहीं करते हैं पृष्ठ पर माउस। :-(
एरिक मिकलसेन

जवाबों:


71

क्या यह पता लगाने का कोई तरीका है कि वर्तमान में कोई कुंजी जावास्क्रिप्ट में है या नहीं?

नहीं। केवल संभावना प्रत्येक निगरानी keyupऔर keydownऔर याद।

समय की कुछ अवधि के बाद कुंजी को दोहराना शुरू होता है, कीड और कीप की घटनाओं को बंद कर देता है।

यह नहीं करना चाहिए आप निश्चित रूप से keypressदोहराएंगे, और कई ब्राउज़रों में भी आपको दोहराया जाएगा keydown, लेकिन अगर keyupदोहराता है, तो यह एक बग है।

दुर्भाग्य से यह बग की पूरी तरह से अनसुनी बग नहीं है: लिनक्स, क्रोमियम और फ़ायरफ़ॉक्स पर (जब इसे जीटीके + के तहत चलाया जा रहा है, जो कि उबंटू जैसे लोकप्रिय डिस्ट्रो में है) दोनों ही आयोजित कीज़ के लिए दोहराए जाने वाले की-की-की-डाउनडाउन बदलाव उत्पन्न करते हैं, जो वास्तव में तेजी से कुंजी को हथौड़े से भेद करना असंभव है।


14
आप, श्रीमान, सज्जन और विद्वान हैं। उबंटू पर क्रोमियम और फ़ायरफ़ॉक्स मेरे प्राथमिक विकास के वातावरण हैं, ताकि मैं जो समस्या देख रहा हूं, वह सही ढंग से बताए। उम्मीद है कि यह बेहतर हो जाएगा, अन्यथा टाइमर हैक समाधान केवल एकमात्र समाधान हो सकता है।
डैनियल एक्स मूर

3
हाँ, यह निराशाजनक है कि इस पर कोई प्रगति नहीं हुई है। Bugs.launchpad.net/ubuntu/+bug/369880 देखें । मैं एक ब्राउज़र गेम लिख रहा हूं और इस पल के लिए मेरा काम संशोधक कुंजियों (शिफ्ट, सीटीएल, आदि) से चिपके रहना है, जो बिल्कुल भी नहीं दोहराते हैं।
बॉबसन

2
नहीं, यह है इसी की कमी से वास्तविक दोहराया keypresses से उन्हें अलग करने के लिए संभव keyupघटनाओं।
mako

4
यह अभी भी मामला है, 8 साल बाद? इस उत्तर को अद्यतन करने की आवश्यकता हो सकती है।
मार्को लवागिनो

3
पार्सिंग सहायता: (Linux && (क्रोमियम || (Firefox && GTK +))
bobince

134

उपयोग करने के अलावा keyupऔर keydownश्रोताओं जब कुंजी है नीचे चला जाता है पर नज़र रखने और उनका बैक अप करने के लिए, वहाँ रहे हैं वास्तव में कुछ गुण है कि आपको बताती हैं कि कुछ चाबियाँ नीचे हैं।

window.onmousemove = function (e) {
  if (!e) e = window.event;
  if (e.shiftKey) {/*shift is down*/}
  if (e.altKey) {/*alt is down*/}
  if (e.ctrlKey) {/*ctrl is down*/}
  if (e.metaKey) {/*cmd is down*/}
}

इस तरह से उन के रूप में सभी ब्राउज़र उत्पन्न घटना वस्तुओं, पर उपलब्ध हैं keydown, keyupऔर keypressहै, तो आप उपयोग MouseMove की जरूरत नहीं है।

मैंने अपने स्वयं के ईवेंट ऑब्जेक्ट को बनाने document.createEvent('KeyboardEvent')और उसके साथ और इस तरह की document.createEvent('KeyboardEvent')खोज करने की कोशिश की e.shiftKey, लेकिन मेरे पास कोई भाग्य नहीं था।

मैं मैक पर क्रोम 17 का उपयोग कर रहा हूं


मैं इसे नए और पुराने दोनों ब्राउज़रों में उपयोग कर रहा हूं, यहां तक ​​कि एचटीए का
जैकब स्टर्नबर्ग

1
क्या इस उत्तर को लागू करने का कोई तरीका है जब कुछ संख्या वर्तमान में नीचे है? मैंने अगर (e.keyCode == 49) {कंसोल.लॉग ("1 डाउन है");}; के साथ प्रयास किया है, लेकिन काम नहीं कर रहा है :(
रॉबर्टो सेपल्वेडा ब्रावो

अरे @ RobertoSepúlvedaBravo रॉबर्ट आपको अगले जवाब पर सवाल का जवाब देता है। ;)
मार्क ओडे सिप

यदि आप शिफ्ट से मतलब रखते हैं तो वास्तव में आपको की। पर e.shiftKey की तलाश नहीं करनी चाहिए। इसके बजाय उदाहरण के लिए onclick पर e.shiftKey का उपयोग करें।
मैकिक

45

मेरा समाधान:

var pressedKeys = {};
window.onkeyup = function(e) { pressedKeys[e.keyCode] = false; }
window.onkeydown = function(e) { pressedKeys[e.keyCode] = true; }

मैं अब जाँच कर सकता हूँ कि क्या कोई कुंजी जाँच के द्वारा स्क्रिप्ट में कहीं और दबाया गया है

pressedKeys["code of the key"]

यदि यह सही है, तो कुंजी दबाया जाता है।


2
चूंकि चाबियाँ पहले से ही एक फ़ंक्शन है, इसलिए एक भिन्न चर नाम बेहतर हो सकता है।
रेवेन

1
यह पता लगाने के लिए काम नहीं करेगा कि सभी मामलों में Alt कुंजी डाउन है या नहीं।
माइकल

1
यह ऊपर का पता लगाने के लिए बहुत अच्छा है / नीचे / छोड़ा / सही
जोनाथन स्पिलर

11

मुझे विश्वास नहीं है कि isKeyDown फ़ंक्शन जैसा कुछ भी है, लेकिन आप अपना स्वयं का लिख ​​सकते हैं।

मूल रूप से, एक सरणी बनाएं जिसकी लंबाई उन कुंजियों की संख्या है जिन्हें आप मॉनिटर करना चाहते हैं। फिर दस्तावेजों / पृष्ठों / नियंत्रणों का उपयोग कर केयूपी और कीडाउन घटनाओं, उस कुंजी की स्थिति के साथ सरणी को अपडेट करें।

फिर एक फ़ंक्शन लिखें जो यह जांचता है कि एक निश्चित कुंजी डाउन है और एक बूल वापस करता है।

var keyEnum = { W_Key:0, A_Key:1, S_Key:2, D_Key:3 };
var keyArray = new Array(4);

function onKeyDown()
{
    // Detect which key was pressed
    if( key == 'w' )
        keyArray[keyEnum.W_Key] = true;
    // Repeat for each key you care about...
}

function onKeyUp()
{
    // Detect which key was released
    if( key == 'w' )
        keyArray[keyEnum.W_Key] = false;
    // Repeat for each key you care about...
}

function isKeyDown(key)
{
    return keyArray[key];
}

जो आप चाहते हैं उसे पूरा करना चाहिए।


1
यह अच्छा है, और वास्तव में समाधान का हिस्सा है, लेकिन यह बग मैं दोहरा रहा बग को संबोधित नहीं कर रहा हूं। देखिए बॉबसन का जवाब।
डैनियल एक्स मूर

4
यह एक अच्छा समाधान नहीं है क्योंकि आप अधिक से अधिक ifs लिख रहे होंगे। एक "कीलिस्ट = {};" एक वस्तु होने के नाते "कीलिस्ट [कुंजी] = सच;" किसी एनम या सीमा की आवश्यकता के बिना, यह स्ट्रिंग इंडेक्स / गुणों का उपयोग करता है और सभी कुंजी के लिए काम करता है।
स्पार्क

5

यह देखने के लिए कि ब्राउज़र में पहले से ही कुछ बनाया गया था, यह जाँचने के लिए यहाँ समाप्त हुआ, लेकिन ऐसा लगता है कि वहाँ नहीं है। यह मेरा समाधान है (रॉबर्ट के जवाब के समान):

"use strict";

const is_key_down = (() => {
    const state = {};

    window.addEventListener('keyup', (e) => state[e.key] = false);
    window.addEventListener('keydown', (e) => state[e.key] = true);

    return (key) => state.hasOwnProperty(key) && state[key] || false;
})();

आप तब जांच सकते हैं कि किसी कुंजी को दबाया गया है या नहीं is_key_down('ArrowLeft')


1

अन्य लोगों ने इस तरह का प्रश्न पहले भी पूछा है (हालांकि मुझे अभी यहां कोई स्पष्ट दोष दिखाई नहीं देता है)।

मुझे लगता है कि उत्तर यह है कि keydownघटना (और इसके जुड़वां keyup) आपके द्वारा प्राप्त सभी जानकारी हैं। दोहराए जाने पर ऑपरेटिंग सिस्टम में बहुत दृढ़ता से वायर्ड किया जाता है, और एक एप्लिकेशन प्रोग्राम को कुंजी की वास्तविक स्थिति के लिए BIOS को क्वेरी करने का अवसर नहीं मिलता है।

आप क्या कर सकते हैं, और शायद अगर आपको यह काम करने की आवश्यकता है, तो प्रोग्राम को कुंजी को डी-बाउंस करना है। अनिवार्य रूप से, आप का मूल्यांकन कर सकते keydownहैं और keyupअपने आप को, लेकिन एक की अनदेखी keyupघटना अगर यह पिछले के बाद बहुत जल्दी हो जाता है keydown... या अनिवार्य रूप से, आप अपनी प्रतिक्रिया में देरी करना चाहिए keyupकाफी देर तक यकीन है कि वहाँ एक और नहीं है होना करने के लिए keydownकी 0.25 सेकंड की तरह कुछ के साथ निम्न इवेंट keyup

इसमें एक टाइमर गतिविधि का उपयोग करना, और पिछले घटनाओं के लिए मिलीसेकंड समय रिकॉर्ड करना शामिल होगा। मैं यह नहीं कह सकता कि यह एक बहुत ही आकर्षक समाधान है, लेकिन ...


2
मैं चिंतित था कि यह इस पर आ सकता है।
डैनियल एक्स मूर

1
/*
Tracks what keys are currently down on the keyboard
*/

function keyboard_module(onUpdate){
    var kb = {};
    var unicode_mapping = {};
    document.onkeydown = function(e){
        var unicode=e.charCode? e.charCode : e.keyCode
        var key = getKey(unicode);
        kb[key] = true;
        if(onUpdate){
            onUpdate(kb);
        }
    }

    document.onkeyup = function(e){
        var unicode=e.charCode? e.charCode : e.keyCode
        var key = getKey(unicode);
        delete kb[key];
        if(onUpdate){
            onUpdate(kb);
        }
    }

    function getKey(unicode){
        if(unicode_mapping[unicode]){
            var key = unicode_mapping[unicode];
        }else{
            var key= unicode_mapping[unicode] = String.fromCharCode(unicode);
        }
        return key;
    }
    return kb;
}

function testing(kb){
    console.log('These are the down keys', kb);
}


var keyboard = keyboard_module(testing);

....
//somewhere else in the code
if(keyboard['K']){/*do something special */}

यकीन नहीं होता अगर String.fromCharCode (यूनिकोड); एक तेज़ लुकअप है या नहीं, इसीलिए मेरे पास unicode_mapping ऑब्जेक्ट है। अगर यह अल्ट्राफास्ट है, तो इस कोड को थोड़ा नीचे ट्रिम करने के लिए बाहर खींचने के लिए कुछ हो सकता है। चूँकि यह कुंजी डाउन के लिए बार-बार कहा जाएगा, इसलिए गति महत्वपूर्ण है, इसलिए मैंने मैपिंग को निराशावादी रूप से जोड़ा।
रॉबोह्र

1

निम्नलिखित कोड वह है जो मैं उपयोग कर रहा हूं:

var altKeyDownCount = 0;
window.onkeydown = function (e) {
    if (!e) e = window.event;
    if (e.altKey) {
        altKeyDownCount++;
        if (30 < altKeyDownCount) {
            $('.key').removeClass('hidden');
            altKeyDownCount = 0;
        }
        return false;
    }
}

window.onkeyup = function (e) {
    if (!e) e = window.event;
    altKeyDownCount = 0;
    $('.key').addClass('hidden');
}

जब उपयोगकर्ता कुछ समय (लगभग 2 सेकंड) के लिए Alt कुंजी को दबाए रखता है, तो लेबल का एक समूह (वर्ग = 'कुंजी छिपा हुआ) दिखाई देता है। जब Alt कुंजी जारी की जाती है, तो लेबल गायब हो जाते हैं। jQuery और बूटस्ट्रैप दोनों का उपयोग किया जाता है।


और क्या होता है अगर "टैब" दबाया जाता है, जबकि ऑल्ट नीचे है?
माइकल

1

मुझे पता है कि यह बहुत पुराना सवाल है, हालांकि बहुत हल्का (~ .5Kb) जावास्क्रिप्ट लाइब्रेरी है जो DOM API का उपयोग करते समय कीबोर्ड इवेंट हैंडलर्स की असंगत फायरिंग को प्रभावी ढंग से "पैच" करता है।

पुस्तकालय Keydrown है

यहां ऑपरेटिव कोड का नमूना है, जिसने श्रोता को सेट करने के लिए कुंजी को बदलकर मेरे उद्देश्यों के लिए अच्छी तरह से काम किया है:

kd.P.down(function () {
  console.log('The "P" key is being held down!');
});

kd.P.up(function () {
  console.clear();
});

// This update loop is the heartbeat of Keydrown
kd.run(function () {
  kd.tick();
});

मैंने अपने क्लाइंट-साइड जावास्क्रिप्ट में कीड्रोएन को एक रेड लाइट ग्रीन लाइट गेम में एक उचित ठहराव एनीमेशन के लिए शामिल किया है जो मैं लिख रहा हूं। आप यहां पूरे खेल को देख सकते हैं । (नोट: यदि आप भविष्य में इसे पढ़ रहे हैं, तो गेम को कोड पूरा और खेलने योग्य होना चाहिए :-D!)

आशा है कि ये आपकी मदद करेगा।


1

मैंने उपरोक्त उत्तरों को स्कैन किया और प्रस्तावित keydown/ keyupदृष्टिकोण केवल विशेष परिस्थितियों में काम करता है। यदि उपयोगकर्ता ऑल्ट-टैब को दूर करता है, या एक नई ब्राउज़र विंडो या टैब खोलने के लिए एक प्रमुख इशारे का उपयोग करता है, तो एक keydownवसीयत पंजीकृत होगी, जो ठीक है, क्योंकि उस समय यह बताना असंभव है कि क्या कुंजी वेब ऐप की निगरानी कर रही है। , या एक मानक ब्राउज़र या OS शॉर्टकट है। ब्राउज़र पेज पर वापस आ रहा है, यह अभी भी लगता है कि कुंजी आयोजित की जाती है, हालांकि इस बीच जारी किया गया था। या कुछ कुंजी बस रखी जाती है, जबकि उपयोगकर्ता माउस के साथ किसी अन्य टैब या एप्लिकेशन पर स्विच कर रहा है, फिर हमारे पृष्ठ के बाहर जारी किया गया है।

संशोधक कुंजियों ( Shiftआदि) के माध्यम से निगरानी की जा सकती mousemoveहै, यह मानते हुए कि वापस टैब करते समय कम से कम एक माउस इंटरैक्शन अपेक्षित है, जो अक्सर होता है।

सबसे अन्य सभी चाबियाँ के लिए (संशोधक को छोड़कर, Tab, Delete, लेकिन सहित Space, Enter), निगरानी keypressसबसे अनुप्रयोगों के लिए काम करेगा - एक कुंजी के दबे आग के लिए जारी रहेगा। keypressफायरिंग की आवधिकता के कारण कुंजी को रीसेट करने में कुछ विलंबता है । असल में, अगर keypressफायरिंग नहीं होती है, तो अधिकांश चाबियों को नियंत्रित करना संभव है। यह, संशोधक के साथ संयुक्त बहुत वायुरोधी है, हालांकि मैंने यह नहीं पता लगाया है कि क्या करना है Tabऔर क्या करना है Backspace

मुझे यकीन है कि वहाँ कुछ पुस्तकालय है जो इस DOM कमजोरी पर अमूर्त है, या शायद कुछ DOM मानक परिवर्तन ने इसका ध्यान रखा, क्योंकि यह एक बहुत बड़ा सवाल है।


keypress अब पदावनत हो गया है। यह क्रोम पर बिल्कुल काम नहीं करता है।
इप्सज्र

0

देखो इस सवाल का जवाब है, और उपयोग onkeyupऔर onkeydownयहाँ उन घटनाओं के बारे में अधिक विशिष्ट जानकारी है।


1
आप जिस लिंक का हवाला देते हैं, वह माउस ईवेंट के लिए है, जहां ऑटो-रिपीट कोई समस्या नहीं है।
कार्ल स्मोत्रिकज़ डेस

की-अप और की-डाउन दोहराना नहीं होगा। की-प्रेस।
क्लाउडीयू

अच्छी तरह से भले ही वे करते हैं, मैं TJMonk15 के समाधान की तरह कुछ कल्पना कर रहा था, बस इसे लिखना नहीं चाहता था
क्लाउडीयू

1
उन दो सवालों पर शब्दांकन एक जैसा है। अजीब संयोग, या कुछ और?
मिच लिंडग्रेन

2
@ मिच: वाह ... यह बहुत अविश्वसनीय है। मुझे नहीं पता कि कोई एक ही सवाल पूछने के लिए दो खाते क्यों बनाएगा। या अधिक संभावना है कि इस व्यक्ति ने बस दूसरे प्रश्न की नकल की और इसे कुंजियों के लिए अनुकूलित किया
क्लोडिउ

0

यह फ़ायरफ़ॉक्स और क्रोम में काम करता है।

मुझे स्थानीय एचटीएमएल फाइल को स्थानीय रूप से खोलने की आवश्यकता थी ( Enterविंडोज में फाइल एक्सप्लोरर में फाइल के चयन के समय दबाकर ), या तो फाइल को देखने के लिए या किसी विशेष ऑनलाइन संपादक में इसे संपादित करने के लिए।

इसलिए मैं इन दोनों विकल्पों में अंतर करना चाहता था- Ctrlदबाते समय -कहा या नहीं, नीचे दबाकर Enter

जैसा कि आप सभी यहां सभी उत्तरों से समझ चुके हैं, यह वास्तव में संभव नहीं है, लेकिन यहां एक तरीका है जो इस व्यवहार की नकल करता है जो मेरे लिए स्वीकार्य था।

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

यदि आप Ctrlफ़ाइल खोलते समय -key दबाए रखते हैं तो जावास्क्रिप्ट कोड में कभी भी कीडड ईवेंट आग नहीं लगेगी। लेकिन एक कीप इवेंट में आग लग जाएगी (जब आप अंत में -की रिलीज करेंगे Ctrl)। कोड कैप्चर करता है।

जैसे ही उनमें से कोई एक होता है कोड भी कीवेन्ट (कीप और कीडाउन दोनों) को बंद कर देता है। इसलिए यदि आप Ctrlफ़ाइल खोलने के बाद -key दबाते हैं , तो कुछ भी नहीं होगा।

window.onkeyup = up;
window.onkeydown = down;
function up(e) {
  if (e.key === 'F5') return; // if you want this to work also on reload with F5.

  window.onkeyup = null;
  window.onkeyup = null;
  if (e.key === 'Control') {
    alert('Control key was released. You must have held it down while opening the file, so we will now load the file into the editor.');
  }         
}
function down() {
  window.onkeyup = null;
  window.onkeyup = null;
}

-3
$('#mytextbox').keydown(function (e) {
            if (e.keyCode == 13) {
                if (e.altKey) {
                    alert("alt is pressed");
                }
            }
 });

यदि आप alt + एंटर दबाते हैं, तो आप अलर्ट देखेंगे।

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