Прошу прощения за неоднозначное название. Трудно было объяснить проблему одним предложением.
Во-первых, моя структура кода выглядит так (с 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>
Проблема вот в чем:
Когда ЕТ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>
Проблема с этим случаем заключается в следующем:
Теперь можно выбрать ЕТ2 после фокусировки ЕТ1. Но, Если я размываю от ЕТ1 за пределы Родителя, «отображение» ЕТ2 не меняется на «Нет».
Если я размываю за пределами Родителя из ЕТ2, 'display' меняется на 'none' (как я хочу, чтобы это работало).
Я больше не знаю, что мне делать. Похоже, это из-за моего незнания. Может ли кто-нибудь указать мне путь или намекнуть?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вот возможное решение. Не самое красивое, но я работаю. Основная идея - сохранить в состоянии, какой элемент имеет фокус. И когда событие размытия происходит на элементе ЕТ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>
)
}
}
Я надеюсь, что это может быть вам полезно.
Большое вам спасибо. Я попробую и еще раз оставлю комментарий.
Я применил этот метод к своему коду. Хотя использование setInterval заставляет меня нервничать, похоже, что это работает. Спасибо.
@SunghoYahng Я разделяю ваши опасения по поводу использования setInterval . Я могу почти гарантировать вам, что это вернется, чтобы укусить вас за задницу в будущем.
В конце концов я решил использовать этот метод.
<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
Потрясающие! Я согласен, интервал не является устойчивым, и это решение выглядит намного проще. Хорошая находка. Спасибо!
Если вы предложите подходящее предложение в заголовке этого вопроса, я буду признателен, если вы дадите мне знать.