Я пытаюсь перевести всплывающее окно в и из поля зрения, когда оно вызывается и отклоняется.
Первоначально отображаемый как null
, при щелчке монтируется скрытый компонент, а затем запускается переход, определенный в CSS, для перехода всплывающего окна в представление.
Во время монтирования компонент регистрирует обработчик щелчков в документе и прослушивает щелчки за пределами всплывающего окна, чтобы сначала вывести его из поля зрения, а затем полностью размонтировать, удалив также прослушиватель событий.
Переходы инициируются изменением атрибута style
моего компонента, но я также пытался использовать className
, который дал точно такие же результаты.
<code>import { useRef, useState, useEffect } from 'react'
/*
* Popup
*
* - [x] auto-dismiss on click outside without hogging the click event
* (i.e. without using `stopPropagation()`)
* - [ ] transition into and out of view
* ! No transition when opening a popup while another is still transitionning out out view
*/
function Popup ({ dismiss }) {
const popupRef = useRef(null)
const [style, setStyle] = useState(hiddenStyles)
useEffect(() => {
setStyle(showingStyles)
}, [])
useEffect(() => {
global.document.addEventListener('click', onClickOutside, false)
return () => {
global.document.removeEventListener('click', onClickOutside, false)
}
}, [])
function onClickOutside (event) {
if (!popupRef.current.contains(event.target)) {
setStyle(hiddenStyles)
setTimeout(dismiss, 900) // TODO Find better way to dismiss (unmount) popup on animation end (and move this responsibility to the Item?)
}
}
return (
<div
className='popup'
ref={popupRef}
style={style}
>
<style jsx>{`
.popup {
z-index: 1;
color: black;
background: white;
border: 1px solid black;
position: absolute;
transition: opacity 0.9s ease;
}
`}</style>
<pre>{JSON.stringify(style, null, 2)}
)
}
/ *
* Всплывающий элемент
*
* - [x] отображать всплывающее окно только при желании, отключать при отклонении
* /
const hiddenStyles = {непрозрачность: 0}
const ShowingStyles = {непрозрачность: 1}
Элемент функции ({id, body}) {
const [showActions, setShowActions] = useState (false)
function openActions () {
setShowActions (правда)
}
function hideActions () {
setShowActions (ложь)
}
вернуть (
{} Тело
{showActions
? (
) : ноль}
)
}
Когда я открываю всплывающие окна по отдельности, выделяя время на то, чтобы закрыть одно, прежде чем открывать следующее, переходы работают. Но если я открою всплывающее окно до того, как другое полностью исчезнет, переход застрянет в своем конечном состоянии с самого начала.
Вопрос: почему?