Why don't transitions on svg work on DOMContentLoaded without delay?

≯℡__Kan透↙ 提交于 2019-11-28 23:34:02

Because that's what DOMContentLoaded does : it fires when the DOM has been parsed, but before the CSSOM has been (and thus before styles have been applied).

If you don't want to wait for the load event,
one way is to force the browser to paint before your script execution (synchronously), by calling offsetXXX property on any document's element (e.g <body>) :

! function() {
  window.addEventListener('DOMContentLoaded', function(){
    document.body.offsetTop; // force a CSS repaint
    var logo2 = document.querySelector("svg");
    logo2.classList.add('start');
  });
}();
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 104.75 32.46">
  <defs>
    <style>
      polygon {
        fill: red;
        transition: opacity 3s ease-out, transform 3s ease-out;
        opacity: 0;
      }
      .start polygon {
        opacity: 1;
      }
      #A1 polygon {
        transform: translate(100px, 100px);
        transition-delay: 1s;
      }
      /*styles after animation starts*/
      .start #A1 polygon {
        transform: translate(0px, 0px);
      }
    </style>
  </defs>
  <title>Logo</title>
  <g id="A1">
    <polygon class="right" points="0.33 31.97 0.81 26.09 13.61 3.84 13.13 9.72 0.33 31.97" />
  </g>
</svg>

As you can see in second example I added a delay of 0 second but it caused the animations to work, why?

Since the CSS object model have not been loaded when the DOMContentLoaded event fires

The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. A very different event load should be used only to detect a fully-loaded page. It is an incredibly popular mistake to use load where DOMContentLoaded would be much more appropriate, so be cautious.

https://developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded

So, adding the css class will not run the animation.

The setTimeOut method is a javascript event, once fired (even with 0 time), it will be added to the end of the current browser execution queue (which in your case will be added after loading the CSS model). Hence the animation will fire properly.

Update:

But jquery domready fires after CSSOM is loaded. So are all these posts on SO are technically incorrect?

domready uses DOMContentLoaded so theoratically speaking, they behave the same way.

Are deferred script tags(both inline or external) executed before CSSOM is loaded?

The script deferred by the defer attribute is executed before the DOMContentLoaded is fired. So the answer is YES.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!