У меня есть этот элемент, который начинается скрытым, а затем анимируется с переходом css при событии щелчка.
Я знаю, что свойство display не может быть анимировано, поэтому я удаляю класс, который применяет display:none, а затем делаю изменение, запускающее переход css, например:
popin.classList.remove('hidden') // removes the display:none property
setTimeout(() => {
popin.classList.remove('closed') // triggers transition
}, 10)
См. Этот скрипт: http://jsfiddle.net/wre2674p/6/ для полного примера.
Я выяснил, что для работы 2-й шаг должен выполняться асинхронно. Поместите его в setTimeout, и он работает ... вроде как. В Chrome работает любая длительность таймаута (даже 0).
Для Firefox и Edge поведение различается. На 100 мс срабатывает каждый раз. Но для тайм-аута, например, 10 мс, переход работает только 50% раз. Поскольку это задерживает анимацию, я хочу, чтобы она была как можно меньше, но при этом обеспечивала стабильную работу.
Я подозреваю, что это связано с перекомпоновкой / перерисовкой, происходящей при изменении свойства display с none на block, но мне не хватает подробностей по этим вопросам, чтобы полностью понять, что происходит и как это предотвратить. Любая идея?



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


Удалите скрытый класс из CSS и HTML, удалите тайм-аут из js. Нет необходимости отображать #popin, так как вы уже скрыли переполнение. Переход может быть запущен напрямую, вы слишком усложняете
document.getElementById('toggle').addEventListener('click', function(e){
let source = e.currentTarget
source.disabled = true
let popin = document.getElementById('popin')
if (popin.classList.contains('closed')){
popin.classList.remove('closed')
}
else{
popin.classList.add('closed')
}
setTimeout(() => {
source.disabled = false
}, 850)
})body{
overflow: hidden;
}
#popin{
display: block;
position: absolute;
top: 0;
right: 0;
width: 400px;
height: 100vh;
/*transform: translate(0, 0);*/
transition: opacity 800ms;
opacity: 1;
background: lightgreen;
}
#popin.closed{
opacity: 0;
z-index: -1;
pointer-events: none;
}<button id = "toggle">toggle</button>
<div id = "popin" class = "closed">
<h1>Popin</h1>
</div>Переход в скрипке - это всего лишь пример. Это своего рода генератор шаблонов, и любой переход можно сделать. Например, для нарастания / затухания отображение не требуется. Я обновил скрипку, чтобы использовать этот пример.
@Antoine ответ отредактирован, но такая же идея, вам не нужно ничего отображать, просто добавьте z-index; -1 в невидимый элемент
z-index не применяется к дочерним элементам. И даже при его применении не особо скрывает элементы. Например, ссылки по-прежнему доступны для просмотра. См. jsfiddle.net/wre2674p/9: при наведении указателя мыши на место, где должна быть ссылка, курсор меняется на указатель, место назначения ссылки становится видимым, и вы можете щелкнуть ссылку, когда она скрыта. Так что это не выход.
@Antoine это связано с тем, что на странице вообще нет контента, см. jsfiddle.net/wre2674p/11, если у вас не будет вообще никакого контента на вашей странице, кроме самого всплывающего окна, тогда это не проблема. вам нужен только z-index -1 для элемента popin, потомки следуют
Конечно, но я не могу контролировать, каким будет содержимое страницы. Из сотен или тысяч ожидаемых применений этого кода закон Мерфи гласит, что в какой-то момент это станет проблемой.
Все страницы будут иметь некоторый контент, и метод z-index работает должным образом.
Одного содержания недостаточно; он должен полностью покрывать интерактивный элемент. Нет гарантии, что каждая интерактивная зона во всплывающем окне (которая может составлять очень большую часть области просмотра) будет иметь перед собой элемент, который полностью ее покрывает.
Если на вашей странице не будет контента для заполнения нормального окна просмотра, это будет выглядеть странно, потому что половина страницы будет пустым пространством за пределами body. Также ваш popin, скорее всего, будет фиксированным, а не абсолютным. Если вы не хотите использовать этот метод, вам придется прослушивать (используя js) до конца перехода на popin, а затем добавить класс, чтобы скрыть элемент. это дополнительный код, который можно было бы сохранить, я не видел сайта, который не может даже заполнить нормальное окно просмотра контентом. Под содержанием я подразумеваю любой div или что угодно
Я также отредактировал ответ, включив pointer-events: none;, поэтому пользователю ничего не будет видно, даже если на вашей странице ничего нет. Вы можете увидеть это здесь jsfiddle.net/wre2674p/12
Удалите скрытый класс из css, уберите таймаут из js. Нет необходимости отображать всплывающее окно, так как вы уже скрыли переполнение. Переход может быть запущен напрямую, вы слишком усложняете