簡體   English   中英

為keydown添加事件監聽器以響應元素

[英]adding event listener for keydown to react element

我正在嘗試在圖像(或div)標簽中為keydown事件添加事件偵聽器。 如果我使用document.addEventListener將其添加到文檔中,它會起作用,但是當我嘗試將其放入我在react中創建的特定元素中時,它就不會起作用(我在代碼中指出了什么有效,什么無效)。 而且無論我將哪種格式放入標記中, handleClick可以正常工作,而handleKey則不能。

class PrescriptionImage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      patient: "",
      rotation: 0
    };
    this.handleKey = this.handleKey.bind(this);
  }

  handleClick() {
    this.setState({rotation: this.state.rotation + 270})
  }

  handleKey(e) {
    e.preventDefault();
    console.log(e);
    if (e.code == 'ArrowLeft') {
      if (e.ctrlKey) {
        this.setState({rotation: this.state.rotation + 270})
      }
    }
  }

  componentDidMount() {
//    document.getElementById("left").addEventListener("keydown", this.handleKey, true); This doesn't work (no error)
//    this.RxImage.addEventListener("keydown", this.handleKey, false); This doesn't work, (can't find addEventListener of "undefined")
//    document.addEventListener("keydown", this.handleKey, false); This works.
    fetch("http://localhost:3333/patientAddress.json")
      .then(res => res.json())
      .then(
        result => {
          this.setState({
            isLoaded: true,
            patient: result.order.patient
          });
        },
        error => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      );
  }

  componentWillUnmount(){
    document.removeEventListener("keydown", this.handleKey, false);
  }

  render() {
    const { error, isLoaded, patient, rotation } = this.state;
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return <img className="prescription-image" style={{width: "98%", height: "98%", transform: `rotate(${rotation}deg)`}} src={"data:image/png;base64," + patient.rx.imageData} onClick={() => this.handleClick()} onKeyDown={this.handleKey} />;
    }
  }
}

ReactDOM.render(<PrescriptionImage />, document.getElementById("left"));

您在這里遇到2個主要問題:

  1. keyDown事件需要div成為焦點。 一種方法是在div添加一個tabindex屬性。 專注onKeyDown之后,您可以在鍵盤上的任何鍵上觸發onKeyDown事件。
  2. 在處理程序中,您嘗試檢查e.code但實際上正確的屬性是e.keycode
    如此說來,您應該仔細閱讀瀏覽器對其的支持,因為某些瀏覽器認為它已棄用。
    這是此事件的可用屬性及其狀態的列表 (例如,選中key )。

編輯
我使用reactref API添加了另一種方法。 這樣,您可以像以前一樣附加事件偵聽器,還可以通過代碼觸發焦點(請參見componentDidMount )。

這是一個正在運行的示例:

 class App extends React.Component { componentDidMount() { this.myDiv.addEventListener('keydown', this.handleKey); this.myDiv.focus(); } componentWillUnmount() { this.myDiv.removeEventListener('keydown', this.handleKey); } handleKey = e => { console.log(e.keyCode); } render() { return ( <div> <div tabIndex="0" onKeyDown={this.handleKey}>click me</div> <div tabIndex="1" ref={ref => this.myDiv = ref}>by ref</div> </div> ); } } ReactDOM.render(<App />, document.getElementById("root")); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="root"></div> 

此實現對我來說效果很好。

class App extends React.Component {

  constructor(props) {
    super(props);
    this.myDiv = React.createRef();
  }

  componentDidMount() {
    this.myDiv.current.addEventListener('keydown', this.handleKey);
    this.myDiv.current.focus();
  }

  componentWillUnmount() {
    this.myDiv.current.removeEventListener('keydown', this.handleKey);
  }

  handleKey = e => {
    console.log(e.keyCode);
  }

  render() {
    return (
      <div>
        <div tabIndex="0" onKeyDown={this.handleKey}>click me</div>
        <div tabIndex="1" ref={this.myDiv}>by ref</div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM