我对“焦点”事件和“模糊”事件有疑问

时间:2018-10-02 09:02:08

标签: javascript html css reactjs dom

对不起,标题模糊。用一个句子很难解释这个问题。

首先,我的代码结构如下(使用JSX)

<Parent>
    <EditableText1 />
    <EditableText2 />
</Parent>

这是我希望它的工作方式:

  • 在默认状态下,ET2(EditableText2)的“显示”为“无”

  • 当“父项”为“焦点”时,ET2的“显示”值为“ flex”

  • 当“父项”为“模糊”时,ET2的“显示”值再次变为“无”

  • 换句话说,如果选择了ET1(可见ET1),则ET2变为可见,并且可以在该状态下编辑ET2。

这是我尝试的方式:

1)

<Parent 
onFocus={() => { this.setState({ visible: 'flex' }) }} 
onBlur={() => { this.setState({ visible: 'none' }) }>
    <EditableText1 />
    <EditableText2 className={css`
display: ${this.state.visible};
`/>
</Parent>

这里的问题是这样:

enter image description here

当ET1成为“焦点”时,出现ET2。但是,如果我尝试选择ET2,则ET1变为“模糊”,因此ET2的“显示”变为“无”。所以我不能选择ET2!

2) 所以我试图防止ET1模糊时冒泡:

<Parent 
onFocus={() => { this.setState({ visible: 'flex' }) }} 
onBlur={() => { this.setState({ visible: 'none' }) }>
    <EditableText1 
onBlur={(e) => { e.stopPropagation() }}
/>
    <EditableText2 className={css`
display: ${this.state.visible};
`/>
</Parent>

这种情况下的问题是:

enter image description here

现在可以在确定ET1之后选择ET2。 但, 如果我从ET1模糊到父级外部,则ET2的“显示”不会更改为“无”。

enter image description here

如果我从ET2中模糊了Parent之外,“显示”将变为“无”(我希望它的工作方式)。

我不知道该怎么办了。似乎是因为我缺乏知识。谁能给我一种方法或给我一个提示?

2 个答案:

答案 0 :(得分:1)

这是一个可能的解决方案。它不是最漂亮的,但我工作。主要思想是存储状态中哪个元素具有焦点。当ET1元素上发生模糊事件时,您需要检查ET2是否具有焦点。为此,您需要创建一个延迟,因为模糊事件将在焦点事件之前触发。而且,如果没有这种延迟,告诉哪个元素具有焦点的状态将不会被更新。

import React from "react";

export default class myClass extends React.Component {
  constructor() {
    super();
    this.beforeBlur = this.beforeBlur.bind(this);
    this.update = this.update.bind(this);
    this.state = {
      whoHasFocus: "none",
      visible: "none"
    };
    this.delay = null;
  }

  beforeBlur(obj) {
    const that = this;
    this.delay = setInterval(() => {
      if (this.state.whoHasFocus !== "ET2") {
        this.update(obj);
      }
      clearInterval(that.delay);
    }, 10);
  }
  update(obj) {
    this.setState(obj);
  }
  render() {
    return (
      <div>
        <input
          type="text"
          onBlur={() => {
            this.beforeBlur({
              visible: "none",
              whoHasFocus: "none"
            });
          }}
          onFocus={() => {
            this.update({
              visible: "flex",
              whoHasFocus: "ET1"
            });
          }}
        />
        <input
          type="text"
          style={{ display: `${this.state.visible}` }}
          onFocus={() => {
            this.update({ whoHasFocus: "ET2" });
          }}
          onBlur={e => {
            this.update({
              visible: "none",
              whoHasFocus: "none"
            })
          }}
        />
      </div>
    )
  }
}

我希望这会对您有所帮助。

答案 1 :(得分:1)

我最终决定使用这种方法。

<div class="Parent">
  <input type="text" id="ET1" />
  <br />
  <input type="text" id="ET2" />
</div>

.Parent:focus-within #ET2 {
  display: flex;
}

#ET2 {
  display: none;
}

我在devpal.io上问了一个问题,得到了这个答案并获得了帮助。谢谢安迪。

  

嘿!   好的,所以他们的响应有效,但是我可能会使用:focus-within的CSS方法:https://www.scottohara.me/blog/2017/05/14/focus-within.html   它具有非常好的浏览器支持:https://caniuse.com/#feat=css-focus-within   我认为您将获得更多的弹性。   希望有帮助