【问题标题】:How to wait for element to be fully rendered to execute CSS transition?如何等待元素完全呈现以执行 CSS 过渡?
【发布时间】:2020-06-15 20:41:32
【问题描述】:

我有一个带有单击事件侦听器的按钮,它调用 2 个不同的函数。第一个函数通过添加一个触发 CSS 过渡到 opacity 0 的类来淡出 div,然后更改 innerHTML,然后删除该类并将 opacity 淡化回 1。

第二个函数创建和 img 元素,将其添加到 div 中,然后向 img 添加一个类,这是一个 CSS 缩放转换。所以它应该是这样的:点击 -> div 淡出 -> div 用新内容淡入 -> 图像出现并变大。

为了使其正常工作,所有这些事件都必须连续发生。我设法使它工作的唯一方法是使用 setTimeouts,这确实不是最好的方法。我已经尝试过承诺、transitionend 事件侦听器、requestAnimationFrame,但这些似乎都不起作用。要么 img 不加载,要么加载已经缩放并且不存在过渡。谁能帮我弄清楚如何设置这些事件,以便每个事件都在触发之前等待最后一个事件的完成?谢谢!

伪代码:

function resetDiv() {
         const div = document.querySelector('#div');
         div.classList.add('cssFadeout');

            div.ontransitionend = () => {
                div.innerHTML = `${text literal HTML stored in a variable}`;
                div.classList.remove('fadeOut');
        }

function generateImg() {

            const newImg = document.createElement('img');
            newImg.src = 'img.png';
            newImg.id = 'newImg';
            div.appendChild(newImg);

            document.querySelector('#newImg').classList.add('cssScale')
}

button.addEventListener('click', (event) => {
    event.preventDefault();

    resetDiv();

    generateImg();

});

【问题讨论】:

    标签: javascript asynchronous transition


    【解决方案1】:

    你可以使用jquery:

    $(()=>{ 回调 })

    或者原版js:

    window.addEventListener('DOMContentLoaded', (event) => {
    console.log('DOM fully loaded and parsed');
    

    });

    这里是 DOMContentLoaded 的 mdn 文档 https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event

    【讨论】:

      【解决方案2】:

      '所以你需要的是页面的重排,它将强制'重新渲染'布局。

      一种方法是使用 el.offsetWidth。 基本上它会发生什么,例如,如果你把它放在这里:

      button.addEventListener('click', (event) => {
          event.preventDefault();
      
          resetDiv();
      
          el.offsetWidth
      
          generateImg();
      
      });
      

      是当调用 offsetWidth 时,JavaScript 正在“重新运行”以检查那一刻元素的宽度,即使元素的宽度没有改变,所以第一个函数运行,第一个动画完成,JavaScript现在正在检查 offsetWidth,然后执行第二个动画。

      因此,声明一个您在 resetDiv 中使用的全局变量,可能是“div”的 querySelector,并检查它在两个函数之间的宽度。

      让我知道这是否有效。

      【讨论】:

      • 我试过了,不幸的是它对我不起作用,我仍然只是得到一个已经缩放的图像。我认为它在图像完全加载到 DOM 之前运行缩放转换,这是我能想出的唯一解释。就像我说的,如果我设置了超时,它会起作用。但是感谢您的帮助!
      【解决方案3】:

      这是基于您的伪代码的建议:

      function resetDiv() {
          const div = document.querySelector('#div');
          div.classList.add('cssFadeout');
      
          div.ontransitionend = () => {
              div.innerHTML = `${text literal HTML stored in a variable}`;
              sky.classList.remove('fadeOut');
              // wait for the transition triggered above to end and then call the other function
              // also remove the call to generateImg() from the click-handler
              sky.ontransitionend = generateImg;
          };
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-29
        • 2017-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多