प्रतिक्रिया में div पर काम नहीं कर रहा onKeyDown घटना


92

मैं प्रतिक्रिया में एक div पर एक कीडाउन घटना का उपयोग करना चाहते हैं। मैं करता हूँ:

  componentWillMount() {
      document.addEventListener("keydown", this.onKeyPressed.bind(this));
  }

  componentWillUnmount() {
      document.removeEventListener("keydown", this.onKeyPressed.bind(this));
  }      

  onKeyPressed(e) {
    console.log(e.keyCode);
  }

  render() {
    let player = this.props.boards.dungeons[this.props.boards.currentBoard].player;
    return (
      <div 
        className="player"
        style={{ position: "absolute" }}
        onKeyDown={this.onKeyPressed} // not working
      >
        <div className="light-circle">
          <div className="image-wrapper">
            <img src={IMG_URL+player.img} />
          </div>
        </div>
      </div>
    )
  }

यह ठीक काम करता है, लेकिन मैं इसे रिएक्ट शैली में अधिक करना चाहूंगा। मैंने कोशिश की

        onKeyDown={this.onKeyPressed}

घटक पर। लेकिन यह प्रतिक्रिया नहीं करता है। यह इनपुट तत्वों पर काम करता है क्योंकि मुझे याद है।

Codepen

मैं यह कैसे कर सकता हूं?


व्यक्तिगत रूप से मुझे आपका दृष्टिकोण पसंद है। यह दस्तावेज़ को कुंजी स्ट्रोक को बांधने का एक अच्छा तरीका है, जो आपके घटक के दायरे से बाहर है। और किसी विशेष तत्व पर ध्यान देने की आवश्यकता नहीं है।
डेनियल

जवाबों:


159

प्रतिक्रिया में एक div पर ईवेंट सुनने में सक्षम होने के लिए आपको tabIndex विशेषता का उपयोग करना चाहिए onKeyDown। सेटिंग tabIndex="0"आपके हैंडलर को आग लगा देनी चाहिए।


2
यह बुरा, राय वाला डिजाइन जैसा लगता है। क्या होगा अगर मैं एक कंटेनर तत्व पर एक बुदबुदाती घटना को संभालना चाहता हूं, लेकिन उस कंटेनर को कभी ध्यान केंद्रित नहीं करना चाहिए?
विल पी।

1
यह मुझे हैक या वर्कअराउंड की तरह लगता है। एक समय हो सकता है जब आपको दिए गए div को एक टैब ऑर्डर बनाए रखने की आवश्यकता हो।
इवने

9
tabIndex={-1}यदि आप एक ऐसे तत्व के साथ काम कर रहे हैं जिसका उपयोग इंटरैक्टिव नहीं है और दस्तावेज़ के टैब क्रम को बदलना नहीं चाहते हैं।
इलियास

1
आपको divI को फोकस करने के लिए tabIndex सेट करना होगा। आप टैबइन्डेक्स को 0,1, -1 पर सेट कर सकते हैं .... लेकिन इससे पहले कि आप ऐसा करें कि webaim.org/techniques/keyboard/tabindex की जांच करें आप संभवतः इसे -1 पर सेट करना चाहते हैं क्योंकि आप इसे प्रोग्रामेटिक रूप से जोड़ तोड़ कर रहे हैं ।
कविता

किसी कारण से यह केवल तभी काम करता है जब मेरे पास टैब में एक <input> तत्व है। या कुछ और जो फोकस्ड हो सकता है। सिर्फ अन्य divs के साथ, यह अभी भी कब्जा नहीं कर रहा है। कोई विचार?
फ्लियन

24

आपको इसे इस तरह से लिखना होगा

<div 
    className="player"
    style={{ position: "absolute" }}
    onKeyDown={this.onKeyPressed}
    tabIndex="0"
  >

यदि onKeyPressedबाध्य नहीं है this, तो इसे तीर फ़ंक्शन का उपयोग करके इसे फिर से लिखने या घटक में बाँधने का प्रयास करें constructor


2
माफ़ करना। मुझे यकीन था, मैंने इस बात को नजरअंदाज कर दिया था। लेकिन यह समस्या नहीं है। यह अभी भी काम नहीं कर रहा है।
माइकल

अद्यतन उत्तर। आपको किसी भी कुंजी को दबाने से पहले या तो डिव पर क्लिक करना चाहिए या फोकस पर लाना चाहिए।
पैंथर

मैंने किया। यह काम नहीं कर रहा है। मैंने ऊपर कोड अपडेट किया। यह DOM कमांड के साथ ठीक काम करता है, लेकिन रिएक्ट स्टाइल में नहीं।
माइकल

क्या आप बता सकते हैं कि क्या काम नहीं कर रहा है? क्या आपका फ़ंक्शन कॉल नहीं हो रहा है या console.logकुछ भी आउटपुट नहीं कर रहा है?
पैंथर

फ़ंक्शन को नहीं कहा जाता है। मेरे पास एक कोडपेन है: codepen.io/lafisrap/pen/OmyBYG । यह रेखाएँ 275 और 307 के बारे में है।
माइकल

7

आप शुद्ध जावास्क्रिप्ट में बहुत अधिक सोच रहे हैं। अपने श्रोताओं को उन रिएक्ट जीवनचक्र के तरीकों से छुटकारा दिलाएं और event.keyइसके बजाय उपयोग करें event.keyCode(क्योंकि यह एक जेएस इवेंट ऑब्जेक्ट नहीं है, यह एक रिएक्ट सिंथेटिक है ।) आपका संपूर्ण घटक इस तरह से सरल हो सकता है (यह मानकर कि आपने किसी विधायक में अपने तरीकों को बाध्य नहीं किया है)।

onKeyPressed(e) {
  console.log(e.key);
}

render() {
  let player = this.props.boards.dungeons[this.props.boards.currentBoard].player;
  return (
    <div 
      className="player"
      style={{ position: "absolute" }}
      onKeyDown={this.onKeyPressed}
    >
      <div className="light-circle">
        <div className="image-wrapper">
          <img src={IMG_URL+player.img} />
        </div>
      </div>
    </div>
  )
}

ठीक इसी तरह से मैं इसे लिखना चाहता था। लेकिन नरक, यह नहीं जा रहा है। यहाँ कोडपेन है: codepen.io/lafisrap/pen/OmyBYG । यदि आप लाइन 275 पर टिप्पणी करते हैं तो कुंजी बोर्ड इनपुट (कर्सर कुंजी) काम नहीं कर रहा है। onKeyDown 307 की पंक्ति में है।
माइकल

KeyCode मैं कर्सर कुंजियों के लिए उपयोग करता हूं, क्योंकि वे कोई वर्ण नहीं लौटाते हैं।
माइकल

1
प्रतिक्रिया जावास्क्रिप्ट ईवेंट ऑब्जेक्ट का उपयोग नहीं करती है, इसलिए कोई कीकोड गुण नहीं है। वह eventवस्तु एक React SyntheticEvent है
स्टील

@ मिचेल मुझे भी पूरी तरह से यकीन नहीं है कि आप एक div पर एक महत्वपूर्ण घटना को कैसे ट्रिगर कर रहे हैं, लेकिन जब मैंने इस कोड को हैंडलर आग के onClickबजाय एक प्रोप के साथ एक बेला में डाल दिया onKeyDown
स्टील

धन्यवाद। यह बताते हैं कि ... प्रमुख घटनाएं हालांकि इनपुट क्षेत्रों में काम करती हैं।
माइकल

2

के साथ जवाब दिया

<div 
    className="player"
    onKeyDown={this.onKeyPressed}
    tabIndex={0}
>

मेरे लिए काम करता है, कृपया ध्यान दें कि टैबइंडेक्स को नंबर की आवश्यकता है, न कि स्ट्रिंग की, इसलिए टैबइंडेक्स = "0" काम नहीं करता है।


शायद दूसरे उत्तर को संपादित करें?
रॉस अट्रिल

0

का उपयोग divके साथ चाल tab_index="0"या tabIndex="-1"काम करता है, लेकिन किसी भी समय उपयोगकर्ता एक राय यह है कि एक तत्व नहीं है ध्यान दे रहा है, तो आप पूरे वेबसाइट पर एक बदसूरत फोकस-रूपरेखा मिलता है। यह outline: noneफ़ोकस में उपयोग करने के लिए div के लिए CSS सेट करके तय किया जा सकता है ।

यहाँ स्टाइल घटकों के साथ कार्यान्वयन है:

import styled from "styled-components"

const KeyReceiver = styled.div`
  &:focus {
    outline: none;
  }
`

और अनुप्रयोग वर्ग में:

  render() {
    return (      
      <KeyReceiver onKeyDown={this.handleKeyPress} tabIndex={-1}>
          Display stuff...
      </KeyReceiver>
    )

-1

आपको कंस्ट्रक्टर में विधि की बाइंडिंग याद आ रही है। यह कैसे प्रतिक्रिया से पता चलता है कि आप इसे करते हैं:

class Whatever {
  constructor() {
    super();
    this.onKeyPressed = this.onKeyPressed.bind(this);
  }

  onKeyPressed(e) {
    // your code ...
  }

  render() {
    return (<div onKeyDown={this.onKeyPressed} />);
  }
}

ऐसा करने के अन्य तरीके हैं, लेकिन यह रनटाइम में सबसे अधिक कुशल होगा।


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