显示块和css转换的解决方法不触发

时间:2016-07-05 17:33:25

标签: javascript css repaint

很抱歉这个问题有很多更新,我很高兴每个人都试图帮助我。我认为下面有一个更清晰的方法来理解这个问题:

如果在更改附加了转换的属性之前将元素的display属性设置为block,则不会应用CSS转换。请考虑以下代码:

CSS:

<div id="creative">
    <span>Sample text</span>
</div>

HTML:

var dom = {};
dom.creative = document.getElementById('creative');
dom.creative.style.display = 'block';
dom.creative.style.opacity = 1;

使用Javascript:

dom.creative.style.display = 'block';
var a = dom.creative.offsetHeight; /* <-- forces repaint */
dom.creative.style.opacity = 1;

该元素将正确显示,但没有任何转换。此问题的解决方法是通过访问元素的一个可视属性来强制重绘:

StackPanel

有一个很好的解决方法吗?并且我的意思是每次我需要更改显示属性和附加转换的属性时不添加额外的javascript代码行。

4 个答案:

答案 0 :(得分:1)

根据您在问题中提供的代码,我在这里采用完全不同的方式,而使用animation代替,这将使整个重绘问题消失

使用脚本更新,将div设置为display: block

var dom = {};
dom.creative = document.getElementById('creative');
dom.creative.style.display = 'none';

var butt = document.getElementById('button');
butt.addEventListener('click', function(e) {
  
  if (dom.creative.style.display == 'block') {
    dom.creative.style.display = 'none';    
  } else {
    dom.creative.style.display = 'block';
  }

})
#creative {
  display: none;
  opacity: 0;
  animation: opac 1s forwards;
  margin: 20px;
}
@keyframes opac {
  100% {
    opacity: 1;
  }
}
button {
  margin: 20px;
}
<button id="button">Toggle display</button>

<div id="creative">
  <span>Sample text</span>
</div>

如果不需要display: none,可以使用transition并简单地切换此类

var dom = {};
dom.creative = document.getElementById('creative');

var butt = document.getElementById('button');
butt.addEventListener('click', function(e) {
  
  dom.creative.classList.toggle('show');

})
#creative {
  opacity: 0;
  transition: opacity 1s;
  margin: 20px;
}
#creative.show {
  opacity: 1;
  transition: opacity 1s;
}
button {
  margin: 20px;
}
<button id="button">Toggle display</button>

<div id="creative">
  <span>Sample text</span>
</div>

对于transition,除offsetHeightsetTimeout解决方案外,还有一个3:rd,具有与切换显示块/无相同的视觉效果,设置高度/宽度为0.

var dom = {};
dom.creative = document.getElementById('creative');

var butt = document.getElementById('button');
butt.addEventListener('click', function(e) {
  
  dom.creative.classList.toggle('show');

})
#creative {
  width: 0;
  height: 0;
  opacity: 0;
  transition: opacity 1s, width 0s 1s;
  margin: 20px 0;
}
#creative.show {
  width: 100%;
  height: auto;
  opacity: 1;
  transition: opacity 1s, width 0s;
}
button {
  margin: 20px 0;
}
<button id="button">Toggle display</button>

<div id="creative">
  <span>Sample text</span>
</div>

<div>Other content</div>

答案 1 :(得分:0)

没有为绝对属性定义过渡,例如 display 。你如何在noneblock之间插入?你不能。但是你可以创建一些在动画完成后运行的后期函数。

使用setTimeout

您可以使用setTimeout并在动画结束后执行一些代码

ANIMATION_TIME = 0.5 * 1000; // in ms

function show(element) {
  // Display property must be set inmediatly; otherwise, the 'show' animation won't be visible until it ends.
  element.style.display = 'block';
  element.opacity = 1;
}

function hide(element) {
  element.opacity = 0;

  setTimeout(function() {
    element.style.display = 'none';
  }, ANIMATION_TIME);
}

// Call examples
var dom = {};
dom.creative = document.getElementById('creative');
show(dom.creative);
hide(dom.creative);

使用动画事件

正如@trustk所指出的那样,你也可以(最好)使用DOM事件:

function show(element) {
  element.style.display = 'block';
  element.opacity = 1;
  element.removeEventListener("animationend", afterHide, false);
}

function afterHide(e) {
  // e.target -> element
  e.target.display = 'none';
}

function hide(element) {
  element.opacity = 0;
  element.addEventListener("animationend", afterHide, false);
}

答案 2 :(得分:0)

如果您只是为不透明度调用添加超时,它应该可以工作!只要不同时调用display和opacity属性,持续时间几乎为零。

var dom = {};
dom.creative = document.getElementById('creative');
dom.creative.style.display = 'block';
setTimeout(function(){
  dom.creative.style.opacity = 1;
},1);

如果jQuery是一个选项,你也可以使用jQuery fadein。然后你可以完全忽略不透明度,只需称它为......

dom.creative.fadeIn(500)

答案 3 :(得分:0)

您可以使用css过渡来显示/隐藏没有javascript的元素。

<!--html-->
<div id="parent">Some parent text
    <div id="creative">Some details</div>
</div>

/*css*/
#parent #creative{
   opacity:0;
   visibility:hidden;
   clip: rect(0px,0px,0px,0px);
   transition: all 0.5s;
}
#parent:hover #creative{/*trigger transition*/
   opacity:1;
   visibility:visible;
   clip: rect(0px,220px,0px,330px);
}