淡入新元素的可靠方法



在我的应用程序中,我每秒创建一个新元素。它们在创建时应淡入。这是我是如何做到的:

window.setInterval(() => {
    const element = document.createElement('div');
    element.classList.add('dot', 'hidden');
    document.getElementById('content').appendChild(element);
    element.classList.remove('hidden');
}, 1000);
.dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, .7);
    margin: 0 5px 5px 0;
    transition: opacity 1s;
}
.hidden {
    opacity: 0;
}

我以为这将使过渡工作,但事实并非如此。我还尝试在延迟后删除hidden类,如下所示:

setTimeout(() => element.classList.remove('hidden'), 100);

这很有趣,因为它只有在延迟足够长时才有效。如果我将其设置为 10 毫秒,一些点会淡入,而其他点会立即出现。

有没有更好,简单和可靠的方法来使其工作,而无需猜测setTimeout()的延迟?

你可以使用CSS动画,避免使用JavaScript,如果它是一个简单的淡入。这只会在 DOM 节点被绘制到屏幕上时运行。如果您需要对动画进行更高级的控制,则可以使用JS。

@keyframes fadein {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.dot {
   display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, .7);
    margin: 0 5px 5px 0;
    animation: 1s linear fadein;
 }

Css transition在隐藏内容时效果最好。

所以这是一个仅使用javascript的解决方案。

window.setInterval(() => {
    const element = document.createElement('div');
    element.classList.add('dot');
    document.getElementById('content').appendChild(element);
    fade(element,0.1);
}, 1000);
// This will inc opacity by 0.1 each 100ms 
function fade(item, i){
i += 0.1;
item.style.opacity = i;
if (i< 1)
setTimeout(()=> fade(item,i), 100);
}
.dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, .7);
    margin: 0 5px 0px 5px;
}
#content {
background:black;
}
<div id="content"></div>

您最初的问题是有意义的,因为您正在添加隐藏类并将其删除在setTimeout块的同一函数中。请记住,只有在函数完成执行后,浏览器才有机会重新渲染。这意味着在添加 hidden 类的行中根本没有用,因为它稍后会在函数中立即删除(在浏览器可以进行渲染之前(。

我建议插入您的 DOM 元素并使用setTimeoutrequestAnimationFrame重置它。此外,由于setIntervalsetTimeout的时间并不完全可靠,因此使用一个元素的 transitionend 事件来触发下一个元素的添加可能是有意义的。

(function() {
  const container = document.getElementById('container');
  let count = 0;
  function addElement() {
    const div = document.createElement('div');
    div.innerHTML = 'item ' + ++count
    container.append(div);
    div.classList.add('item')
    div.addEventListener('transitionend', addElement)
    setTimeout(function() {
      div.classList.add('show')
    }, 0)
  }
  addElement()
})()
div {}
div.item {
  opacity: 0;
  transition: opacity 1s;
}
div.item.show {
  opacity: 1;
}
<hr>
<div id="container">
</div>

相关内容

最新更新