将元素添加到 DOM 时,转换无法正常工作[重复]

问题描述 投票:0回答:2

当我在 JavaScript 中触发函数时,我试图淡入 Toast 消息。

我希望该函数创建元素,将其添加到 dom,然后使用 css 过渡将其淡入,然后使用相同的过渡将其淡出,然后将其从 dom 中删除。

除非我将其包裹在超时中,否则淡出将不起作用。

编辑::里卡德
我添加了一个按钮来显示吐司。

function flashToast(msg, duration) {
  duration = duration || 3000;

  // create the toast element
  const toastElement = document.createElement("p");
  toastElement.innerHTML = msg;

  toastElement.classList.add("toast");

  // add it to the dom

  document.body.appendChild(toastElement);

  // fade in won't work unless I wrap it in a timeout
  setTimeout(function() {
    toastElement.style.opacity = "1";
  }, 1);

  // remove it after the duration is over
  setTimeout(function() {
    toastElement.style.opacity = "0";
  }, duration - 500);

  // start fading it out 500ms before removing it
  setTimeout(function() {

    document.body.removeChild(toastElement);
  }, duration);
}
.toast {
  display: inline-block;
  font-size: 1.2rem;
  padding: 0.8em 1em;
  border-radius: 5rem;
  color: #eaeaea;
  background: #606060;
  background: rgba(96, 96, 96, 0.7);
  position: absolute;
  bottom: 2%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* opacity is 0 when first enjected */
  opacity: 0;
  transition: opacity 500ms ease;
}
<button onclick="flashToast('Toast!')">Show toast</button>

javascript html css css-transitions
2个回答
2
投票

观看 Rickard Elimää 推荐的视频后。我发现 requestAnimationFrame 解决了这个问题。这是最终的 JavaScript:

function flashToast(msg, duration) {
  duration = duration || 3000;
 
  // create the toast element
  const toastElement = document.createElement("p");
  toastElement.innerHTML = msg;

  toastElement.classList.add("toast");

  // add it to the dom
  document.body.appendChild(toastElement);

  requestAnimationFrame(function() {
    toastElement.style.opacity = "1";
  });

  // remove it after the duration is over
  setTimeout(function() {
    toastElement.style.opacity = "0";
  }, duration - 500);

  // start fading it out 500ms before removing it
  setTimeout(function() {
    document.body.removeChild(toastElement);
  }, duration);
}

1
投票

您必须使用 setTimeout 是因为 javascript 与事件循环的工作方式有关。这是一个非常好的视频,解释了您需要了解的有关 javascript 的基本知识。 (嘿,我已经从事 Web 开发五年了,但使用 javascript 有 20 年了,今年夏天才知道这一点。)

杰克·阿奇博尔德:循环中

如果您不想使用超时,则可以使用动画。缺点是具体时间很难控制。如果您从不透明度 0 开始,然后将不透明度 1 设置为 15%,这将导致淡入速度变慢,从而延长 Toast 持续时间。

function flashToast(msg, duration) {
  duration = duration || 3000;

  const toastElement = document.createElement("p");
  toastElement.innerHTML = msg;

  toastElement.classList.add("toast");
  
  // Added 
  toastElement.style.setProperty("--duration", duration + "ms");

  document.body.appendChild(toastElement);

  setTimeout(function() {
    document.body.removeChild(toastElement);
  }, duration);
}
.toast {
  display: inline-block;
  font-size: 1.2rem;
  padding: 0.8em 1em;
  border-radius: 5rem;
  color: #eaeaea;
  background: #606060;
  background: rgba(96, 96, 96, 0.7);
  position: absolute;
  bottom: 2%;
  left: 50%;
  transform: translate(-50%, -50%);
  
  /* NEW */
  animation: fade var(--duration) linear;
}

@keyframes fade {
  0%   {opacity: 0;}
  15%  {opacity: 1;}
  85%  {opacity: 1;}
  100% {opacity: 0;}
}
<button onclick="flashToast('Toast!')">Show toast</button>

© www.soinside.com 2019 - 2024. All rights reserved.