CSS转换后隐藏元素

时间:2019-01-07 14:52:07

标签: javascript html css css-transitions reflow

我将此元素隐藏起来,然后在单击事件中通过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,它每次都起作用。但是对于例如的超时10ms时,过渡可能仅发生50%的时间。由于它会延迟动画的播放时间,因此我希望将其保持在尽可能低的水平,同时确保其始终如一地工作。

我怀疑这与将display属性从none更改为block时发生的重排/重绘有关,但是我缺少有关这些主题的详细信息以完全了解正在发生的事情以及如何防止它。有想法吗?

1 个答案:

答案 0 :(得分:0)

从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>