React Redux onBlur事件未在Safari和Firefox中触发 [英] React Redux onBlur event not firing in Safari and Firefox

查看:63
本文介绍了React Redux onBlur事件未在Safari和Firefox中触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这似乎在Chrome和Edge中完美运行.我有一个工具提示,需要弹出按钮的onClick,然后消失onBlur.由于某些原因,onBlur事件根本无法在Safari或Firefox上触发.

This seems to work perfectly in Chrome and Edge. I have a tooltip that needs to pop up onClick of the button, and then disappear onBlur. For some reason the onBlur event does not fire at all on Safari or Firefox.

我尝试在handleBlur中登录到控制台,但并没有达到目的,好像onBlur在此上下文中不存在.

I've tried logging to the console in handleBlur and it does not get that far, it is as if onBlur does not exist in this context.

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>
    );
  }
}

推荐答案

我所知道的是,我永远无法获得一个元素(很可能是< input/> )集中在mount上,反应,可能是因为 render() s,所以我使用 setTimeout(()=> input.focus(),0)使其异步.因此,似乎焦点处理存在问题...

All I know is that I could never get an element (most likely an <input />) focused on mount with React, probably because of render()s, so I use setTimeout(() => input.focus(), 0) to make it async. So, it seems there are issues with focus handling...

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

但是当用户将鼠标按钮放出时,您将永远不会触发 onMouseUp .

But when user release the mouse button out of the button, you'll never trigger the onMouseUp.

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

A better workaround consists in simulating a click out:

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/> 或其子节点之一,则触发 click out 伪事件

Any time you click on your document, if target is not <button /> or one of its child nodes, trigger the click out pseudo event

这篇关于React Redux onBlur事件未在Safari和Firefox中触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆