Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!doctype html>
<head>
  <style>
    button {
      margin: 0.5rem;
    }
    .opacity-0 {
      opacity: 0;
    }
    .opacity-100 {
      opacity: 1;
    }
    .container {
      font-family: monospace;
      border: 1px solid black;
      padding: 0.25rem 0.75rem;
      margin: 0.5rem;
      transition: opacity linear 1s;
    }
  </style>
</head>
<body>
  <div id="wrapper">
    <button>Toggle</button>
    <div id="c5" class="container">Click toggle after the element is invisible to see the bug</div>
  </div>
  <script>
    let wrapper = document.querySelector("#wrapper");
    let containers = Array.from(document.querySelectorAll(".container"));
    let show = true;
    let compute = false;
    let disconnect = false;
    function play(el) {
      let from = show ? "opacity-0" : "opacity-100";
      let to = show ? "opacity-100" : "opacity-0";
      // 1. Add element to DOM
      wrapper.append(el);
      // 2. Read a computed property value _before_ adding the class
      window.getComputedStyle(el).getPropertyValue("z-index");
      // 3. Add a class representing the current state of the element
      // e.g. if we're showing the element then it starts out hidden (opacity-0)
      // otherwise it starts out visible (opacity-100)
      el.classList.add(from);
      // Normally an element has 0 animations at this point
      // However, if we read a computed property value _before_ adding the class
      // the element will have 1 animation
      console.log("Element %s has %d animation(s)", el.id, el.getAnimations().length);
      requestAnimationFrame(() => {
        // 4. Change the class list to trigger the transition
        el.classList.remove(from);
        el.classList.add(to);
        // Normally an element has 1 animation at this point
        // However, if we read a computed property value _before_ adding the class
        // the element will have 0 animations
        console.log("Element %s has %d animation(s)", el.id, el.getAnimations().length);
        el.addEventListener(
          "transitionend",
          () => {
            // Reset the element's state
            el.classList.remove(to);
            // Remove element from DOM (if needed)
            show || el.remove();
          },
          { once: true },
        );
      });
    }
    // Log when animations are done or cancelled for debugging purposes
    containers.forEach((el) => {
      el.addEventListener("transitionrun", () => console.log(el, "transitionrun"));
      el.addEventListener("transitionstart", () => console.log(el, "transitionstart"));
      el.addEventListener("transitionend", () => console.log(el, "transitionend"));
      el.addEventListener("transitioncancel", () => console.log(el, "transitioncancel"));
    });
    // Start animation(s)
    document.querySelector("button").addEventListener("click", () => {
      show = !show;
      containers.forEach(play);
    });
  </script>
</body>
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers