У меня вопрос о событиях "Фокус" и "Размытие"

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

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

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

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

  • В состоянии по умолчанию для ET2 (EditableText2) отображается значение none.

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

  • Когда «Родительский» установлен на «Размытие», значение «display» ЕТ2 снова становится «none».

  • Другими словами, если выбран ЕТ1 (ЕТ1 виден), ЕТ2 становится видимым, и ЕТ2 можно редактировать в этом состоянии.

Вот как я пробовал:

1)

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

Проблема вот в чем:

У меня вопрос о событиях &quot;Фокус&quot; и &quot;Размытие&quot;

Когда ЕТ1 становится «фокусом», появляется ЕТ2. Однако, если я попытаюсь выбрать ЕТ2, ЕТ1 станет «размытым», поэтому «Отображение» ЕТ2 станет «Нет». Так что не могу выбрать ЕТ2!

2) Поэтому я попытался предотвратить образование пузырей, когда ЕТ1 размыт:

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

Проблема с этим случаем заключается в следующем:

У меня вопрос о событиях &quot;Фокус&quot; и &quot;Размытие&quot;

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

У меня вопрос о событиях &quot;Фокус&quot; и &quot;Размытие&quot;

Если я размываю за пределами Родителя из ЕТ2, 'display' меняется на 'none' (как я хочу, чтобы это работало).

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

Если вы предложите подходящее предложение в заголовке этого вопроса, я буду признателен, если вы дадите мне знать.

Sungho Yahng 02.10.2018 11:07
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
1
103
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вот возможное решение. Не самое красивое, но я работаю. Основная идея - сохранить в состоянии, какой элемент имеет фокус. И когда событие размытия происходит на элементе ЕТ1, вам нужно проверить, имеет ли ЕТ2 фокус или нет. Для этого вам нужно создать задержку, потому что событие размытия срабатывает перед событием фокуса. И без этой задержки состояние, указывающее, какой элемент находится в фокусе, еще не будет обновлено.

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

Я надеюсь, что это может быть вам полезно.

Большое вам спасибо. Я попробую и еще раз оставлю комментарий.

Sungho Yahng 02.10.2018 15:53

Я применил этот метод к своему коду. Хотя использование setInterval заставляет меня нервничать, похоже, что это работает. Спасибо.

Sungho Yahng 03.10.2018 12:21

@SunghoYahng Я разделяю ваши опасения по поводу использования setInterval . Я могу почти гарантировать вам, что это вернется, чтобы укусить вас за задницу в будущем.

ESR 04.10.2018 07:51
Ответ принят как подходящий

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

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

Hey there! Ok, so their response works, but I'd probably take a CSS approach using :focus-within: https://www.scottohara.me/blog/2017/05/14/focus-within.html It's got really good browser support: https://caniuse.com/#feat=css-focus-within I think you'll get a lot more resilience approaching it with that. Hopefully that helps

Потрясающие! Я согласен, интервал не является устойчивым, и это решение выглядит намного проще. Хорошая находка. Спасибо!

J.Lindebro 04.10.2018 10:25

Другие вопросы по теме