css转换后隐藏元素
Posted
技术标签:
【中文标题】css转换后隐藏元素【英文标题】:Hiding element after css transition 【发布时间】:2019-06-02 06:02:44 【问题描述】:我有一个开始隐藏的元素,然后在单击事件时使用 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/。
我发现为了工作,第二步必须异步完成。把它放在setTimeout
中,它就可以工作了……有点。在 Chrome 中,任何超时时间都有效(甚至为 0)。
对于 Firefox 和 Edge,行为会有所不同。 100ms,每次都有效。但是对于例如超时10 毫秒,转换可能只有 50% 的时间。由于它会延迟动画,我希望将其保持在尽可能低的水平,同时确保它始终如一地工作。
我怀疑这与将display
属性从none
更改为block
时发生的回流/重绘有关,但我缺乏关于这些主题的详细信息以完全了解正在发生的事情以及如何防止它。有什么想法吗?
【问题讨论】:
从css中移除隐藏类,从js中移除timeout。由于您已经隐藏了溢出,因此无需显示任何 popin。过渡可以直接触发,你把事情复杂化了 【参考方案1】:从 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 回答已编辑但相同的想法,您不需要显示 none,只需将z-index; -1
添加到不可见元素
z-index 不适用于子元素。即使在应用它时,它也不会真正隐藏元素。例如,链接仍然是可点击的。请参阅jsfiddle.net/wre2674p/9:当您将鼠标悬停在链接应位于的位置时,光标变为指针,链接目标可见,您可以在链接隐藏时单击链接。所以这不是一个解决方案。
@Antoine 这是因为页面上根本没有内容,请参阅jsfiddle.net/wre2674p/11,除非您的页面上根本没有任何内容,除了 popin 本身这不是问题。你只需要 popin 元素上的 z-index -1,孩子们跟随
当然可以,但是我无法控制页面的内容。在此代码的成百上千次预期用途中,墨菲定律表明这将成为一个问题。以上是关于css转换后隐藏元素的主要内容,如果未能解决你的问题,请参考以下文章