React Redux onBlur事件未在Safari和Firefox中触发

时间:2017-06-08 09:34:00

标签: javascript reactjs firefox redux react-redux

这似乎在Chrome和Edge中完美运行。我有一个工具提示,需要弹出点击按钮,然后消失在Blur上。出于某种原因,onBlur事件在Safari或Firefox上根本不会触发。

我已尝试在handleBlur中登录到控制台,并且它没有那么远,就好像onBlur在此上下文中不存在。

class Tooltip extends Component {
  componentWillUnmount() {
    this.closeActiveTooltip();
  }

  handleKeyPress = (event) => {
    if (event.keyCode === 27) { // Esc key
      this.closeActiveTooltip();
    }
  }

  handleBlur = () => {
    if (this.props.activeTooltip === this.props.name) {
      // setTimeout is for link click
      setTimeout(this.closeActiveTooltip, 100);
    }
  }

  closeActiveTooltip = () => {
    const { activeTooltip, closeTooltip } = this.props;

    if (activeTooltip) {
      closeTooltip(activeTooltip);
    }
  }

  render() {
    const {
      isOpen,
      text,
      link,
      position,
    } = this.props;
    const popupClassName = getClassNameFor(s, 'popup', `${isOpen && 'open'} ${position}`);
    const linkElement = (
      <div className={s.link}>
        <a
          href={link}
          target="_blank"
          rel="noopener noreferrer"
        >
          More info here
        </a>
      </div>
    );

    return (
      <button
        type="button"
        className={s.root}
        onClick={this.props.toggleTooltip}
        onBlur={this.handleBlur}
        onKeyDown={this.handleKeyPress}
      >
        <svg className={s.icon}>
          <use xlinkHref="#more-info" />
        </svg>
        <div className={popupClassName}>
          {text}
          {link && linkElement}
        </div>
      </button>
    );
  }
}

1 个答案:

答案 0 :(得分:1)

我所知道的是,我永远不会得到一个元素(很可能是<input />)专注于使用React挂载,可能是因为render() s,所以我使用setTimeout(() => input.focus(), 0)来制作它异步。所以,焦点处理似乎存在问题......

一个简单的解决方法是:

<button
    onClick={this.handleAction}
    onMouseDown={this.handleFocus}
    onMouseUp={this.handleBlur} />

但是当用户从按钮中释放鼠标按钮时,您永远不会触发onMouseUp

更好的解决方法是模拟点击

class Tooltip extends Component {
    componentDidMount() {
        document.body.addEventListener('click', this.handleClickOut, false);
    }

    componentWillUnmount() {
        document.body.removeEventListener('click', this.handleClickOut, false);
    }

    handleClickOut = event => {
        if(event.target != this.refs.btn) { // Actually more complicated, event.target can be a child of button (icon, span, etc)
            this.handleBlur();
        }
    }

    handleBlur() {}

    render() {
        return (
            <button
                ref='btn'
                type="button"
            >
                {text}
            </button>
        );
    }
}

可能包含一个包裹按钮的组件

<ClickOut onClickOut={this.handleBlur}>
    <button
        onClick={this.handleAction}
        onMouseDown={this.handleFocus} />
</ClickOut>

如果您单击文档,如果target不是<button />或其中一个子节点,则触发点击伪事件