onBlur 没有在 <img /> 标签上被调用?

onBlur is not getting Called on <img />tag?

我正在尝试在图像页面上调用 onBlur,但它不起作用。这是代码: 这是一个 class 组件

showToolTip = () => {
    console.log("called");
    this.setState({ copyMessage: "Copy To Clipboard" });
};

copyToClipboard = () => {
    this.copy_span.select();
    document.execCommand("copy");
    this.setState({ copyMessage: "Copied!" }, () => {
        this.copyRef.current.focus();
    });
};
<img
    ref={this.copyRef}
    data-tip
    data-for="clip"
    src={require('../../assets/img/copy.svg')}
    alt={''}
    className="copy_link_image"
    onBlur={this.showToolTip}
    onClick={this.copyToClipboard}
/>
<ReactTooltip
    id="clip"
    type="dark"
>
    <span>{this.state.copyMessage}</span>
</ReactTooltip>

我做错了什么?

与流行的看法相反,您可以将 onBlur 与 img 标签一起使用: https://reactjs.org/docs/events.html#focus-events

onFocus onBlur

These focus events work on all elements in the React DOM, not just form elements.

为 onBlur 添加一个名为 removeMessage 的新回调

removeMessage = () => {
    this.setState({ copyMessage: "" })
}

showToolTip = () => {
    console.log("called");
    this.setState({ copyMessage: "Copy To Clipboard" });
};

copyToClipboard = () => {
    this.copy_span.select();
    document.execCommand("copy");
    this.setState({ copyMessage: "Copied!" }, () => {
      this.copyRef.current.focus();
    });
};

将 showToolTip 更改为 onMouseEnter 并为 onBlur 添加新的 removeMessage 回调

<img 
    ref={this.copyRef} data-tip data-for="clip" src={require( "../../assets/img/copy.svg")} alt={ ""} className="copy_link_image" 
    tabindex = "0"
    onFocus={this.showToolTip}
    onBlur={this.removeMessage} 
    onMouseEnter={this.showToolTip}
    onMouseOut={this.removeMessage}
    onClick={this.copyToClipboard} 
/>

onBlur 事件不适用于 img 标签,它仅适用于输入字段。 您可以在单击文档时附加事件处理程序,您可以将状态更改回默认值。

希望对您有所帮助。

您不能 "focus" 图片,除非您有互动元素或使用标签导航到它。尝试在包装器 div 上添加一个交互式元素,如下所示:

<a href="#" onBlur={this.showToolTip} onClick={this.copyToClipboard}>
  <img ref={this.copyRef} data-tip data-for="clip" src={require( "../../assets/img/copy.svg")} alt={ ""} className="copy_link_image"  />
</a>

您还可以在 tabindex 的帮助下聚焦一个 - 这样:

<img ref={this.copyRef} data-tip data-for="clip" src={require( "../../assets/img/copy.svg")} alt={ ""} className="copy_link_image" onBlur={this.showToolTip} onClick={this.copyToClipboard} tabindex="0" />

您可以通过在单击图像后添加和删除整个 window 事件侦听器来完成您正在尝试做的事情:

const ReactTooltip = props => <div>{props.children}</div>

class App extends React.Component {
  state = {
    copyMessage: ""
  }

  copyRef = React.createRef()

  showToolTip = () => {
    console.log("Tooltip");
    window.removeEventListener('click', this.sortOfBlur);
  };

  sortOfBlur = (e) => {
    if (e.target !== this.copyRef.current) {
      this.showToolTip();
    }
  }

  copyToClipboard = () => {
    console.log('Copied!');
    window.addEventListener('click', this.sortOfBlur);
  };

  render() {
    return (<div>
      <img ref={this.copyRef} data-tip="data-tip" data-for="clip" src="https://lorempixel.com/400/200" alt={""} className="copy_link_image" onClick={this.copyToClipboard}/>
      <ReactTooltip id="clip" type="dark">
        <span>{this.state.copyMessage}</span>
      </ReactTooltip>
    </div>)
  }
}

ReactDOM.render(<App/>, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>