【问题标题】:Transition not working correctly when element is added to the DOM将元素添加到 DOM 时转换无法正常工作
【发布时间】:2020-11-06 00:26:15
【问题描述】:

当我在 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


    【解决方案1】:

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

    Jake Archibald: In The Loop

    如果您不想使用超时,则可以使用动画。缺点是很难控制特定时间。如果您从不透明度 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>

    【讨论】:

    • 谢谢!我看了你推荐的视频,发现“requestAnimationFrame”解决了这个问题。
    【解决方案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);
    }
    

    【讨论】:

      猜你喜欢
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 2013-09-07
      • 1970-01-01
      • 2021-09-20
      • 2015-02-24
      • 2020-08-08
      • 2016-07-16
      相关资源
      最近更新 更多