У меня есть вопрос о событии Focus и Blur - PullRequest
0 голосов
/ 02 октября 2018

Извините за неоднозначное название.Трудно было объяснить проблему одним предложением.

Во-первых, моя структура кода выглядит следующим образом (с JSX)

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

Вот как я хочу, чтобы это работало:

  • В состоянии по умолчанию «показ» ET2 (EditableText2) равен «none»

  • Когда «Родитель» равен «Фокус», «отображение» ЕТ2значение становится «flex»

  • Когда «Parent» равен «Blur», значение «display» ET2 снова становится «none»

  • В другихслова, если выбран 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

Теперь возможно выбрать ET2 после фокусировки ET1.Но, если я размываю от ЕТ1 наружу от Родителя, «отображение» ЕТ2 не меняется на «нет».

enter image description here

Если я размываю снаружиРодитель из ET2, «display» меняется на «none» (так, как я хочу, чтобы оно работало).

Я не знаю, что делать дальше.Кажется, это из-за моего недостатка знаний.Кто-нибудь может дать мне путь или дать подсказку?

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

В конце концов я решил использовать этот метод.

<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, получил ответ и получил помощь.Спасибо, Энди.

Привет!Хорошо, так что их ответ работает, но я бы, вероятно, воспользовался подходом CSS с использованием :focus-within: https://www.scottohara.me/blog/2017/05/14/focus-within.html У него действительно хорошая поддержка браузера: https://caniuse.com/#feat=css-focus-within Я думаю, вы получите гораздо большую устойчивостьподходя к этому с этим.Надеюсь, это поможет

0 голосов
/ 02 октября 2018

Вот возможное решение.Это не самая красивая, но я работаю.Основная идея состоит в том, чтобы сохранить, какой элемент имеет фокус в состоянии.И когда событие размытия происходит на элементе 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>
    )
  }
}

Надеюсь, это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...