onKeyDown event not working on divs in React

前端 未结 7 996
北恋
北恋 2020-12-02 11:11

I want to use a keyDown event on a div in React. I do:

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


        
相关标签:
7条回答
  • 2020-12-02 11:26

    You need to write it this way

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

    If onKeyPressed is not bound to this, then try to rewrite it using arrow function or bind it in the component constructor.

    0 讨论(0)
  • 2020-12-02 11:27

    You're missing the binding of the method in the constructor. This is how React suggests that you do it:

    class Whatever {
      constructor() {
        super();
        this.onKeyPressed = this.onKeyPressed.bind(this);
      }
    
      onKeyPressed(e) {
        // your code ...
      }
    
      render() {
        return (<div onKeyDown={this.onKeyPressed} />);
      }
    }
    

    There are other ways of doing this, but this will be the most efficient at runtime.

    0 讨论(0)
  • 2020-12-02 11:31

    You have to prevent default event from triggering.

    onKeyPressed(e) {
       e.preventDefault();
       console.log(e.key);
    }
    
    0 讨论(0)
  • 2020-12-02 11:32

    Using the div trick with tab_index="0" or tabIndex="-1" works, but any time the user is focusing a view that's not an element, you get an ugly focus-outline on the entire website. This can be fixed by setting the CSS for the div to use outline: none in the focus.

    Here's the implementation with styled components:

    import styled from "styled-components"
    
    const KeyReceiver = styled.div`
      &:focus {
        outline: none;
      }
    `
    

    and in the App class:

      render() {
        return (      
          <KeyReceiver onKeyDown={this.handleKeyPress} tabIndex={-1}>
              Display stuff...
          </KeyReceiver>
        )
    
    0 讨论(0)
  • 2020-12-02 11:33

    You're thinking too much in pure Javascript. Get rid of your listeners on those React lifecycle methods and use event.key instead of event.keyCode (because this is not a JS event object, it is a React SyntheticEvent). Your entire component could be as simple as this (assuming you haven't bound your methods in a constructor).

    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>
      )
    }
    
    0 讨论(0)
  • 2020-12-02 11:36

    You should use tabIndex attribute to be able to listen onKeyDown event on a div in React. Setting tabIndex="0" should fire your handler.

    0 讨论(0)
提交回复
热议问题