使用CSS过渡Firefox淡入

时间:2018-01-31 03:29:58

标签: javascript jquery css firefox settimeout

当用户点击按钮时,我希望使用CSS转换淡化叠加层。

overlay元素的样式为:transition: opacity 1s

我使用jQuery将显示从none设置为block,然后在短暂延迟后将不透明度设置为1:

overlay.css('display', 'block');

setTimeout(function() {
    overlay.css('opacity', 1);
}, 10);

如果没有延迟,叠加层将以完全不透明度显示。

这适用于大多数浏览器(Chrome,Safari,Internet Explorer 11,Edge ...),但在Firefox中,过渡通常不会发生。较长的超时使Firefox更可靠,更短的超时将使其几乎不会显示转换。

如何在设置不透明度之前可靠地等待display: block应用?



function show() {
  $('#square').css('display', 'block');

  setTimeout(function() {
    $('#square').css('opacity', 1);
  }, 5);
}

function hide() {
  $('#square').css('display', 'none');
  $('#square').css('opacity', 0);
}

#square {
  width: 100px;
  height: 100px;
  background-color: red;
  opacity: 0;
  display: none;
  transition: opacity 1s;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onClick="show()">Show</button>
<button onClick="hide()">Hide (no animation)</button>
<div id="square"></div>
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:1)

不确定原因,但似乎Firefox新的 Quantum CSS有问题,因为你正在做的事情应该有效

玩弄它,我以为我试图将不透明度更改放在请求动画帧中,但是失败的次数与代码的次数相同

然后,我嵌套了requestAnimationFrame ...它似乎工作。我所能推测的是,当第二个动画帧被触发时(即元素显示后大约16到32ms),仍然不可见元素的渲染完成,因此可以进行动画(我做这个当我走的时候,你能说出来吗?

&#13;
&#13;
function show() {
  $('#square').css('display', 'block');
  requestAnimationFrame(() => requestAnimationFrame(() => $('#square').css('opacity', 1)));
}

function hide() {
  $('#square').css('display', 'none');
  $('#square').css('opacity', 0);
}
&#13;
#square {
  width: 100px;
  height: 100px;
  background-color: red;
  opacity: 0;
  display: none;
  transition: opacity 1s;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onClick="show()">Show</button>
<button onClick="hide()">Hide (no animation)</button>
<div id="square"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

通过获取元素的offsetHeight而不是超时来强制重排似乎在所有浏览器中都能保持一致:

$('#square').css('display', 'block');
$('#square').get(0).offsetHeight;
$('#square').css('opacity', 1);

答案 2 :(得分:0)

使用可见性

像这样:

<DOCTYPE html>
<html>
<head>
<style>
[ui="overlay"]
{
  display: block; /* always a block */
  z-index: 2;

  position: fixed;
  left: 0; 
  top: 0;
  width: 100vw; /* 100% of viewport width */
  height: 100vh; /* 100% of viewport height */

  background-color: rgba(0,0,0,0.8);

  transition-property: visibility, opacity;
  transition-duration: .0s, .5s; /* change only .5s opacity duration */
}

[ui="overlay"][ui-state="0"]
{
  transition-delay: .5s, .0s; /* visibility delay = opacity duration */
  transition-timing-function: ease-out;
  visibility: hidden;
  opacity: 0;
}

[ui="overlay"][ui-state="1"]
{
  transition-delay: .0s, .0s; /* no visibility delay */
  transition-timing-function: ease-in;
  visibility: visible;
  opacity: 1;
}
</style>
</head>
<body>

<div ui="overlay" id="mainOverlay" ui-state="0">
  <button ui="target-state" ui-target="#mainOverlay" ui-target-state="0">X</button>
</div>

<button ui="target-state" ui-target="#mainOverlay" ui-target-state="1">Show overlay</button>

<script src="http://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>

<script>
$(document).ready(function(){
  $('[ui="target-state"]').on('click',function(){
    var t = $(this).attr('ui-target');
    var s = $(this).attr('ui-target-state');
    $(t).attr('ui-state', s);
  });
});
</script>
</body>
</html>