为什么svg上的转换没有延迟地在DOMContentLoaded上工作?

use*_*782 12 html javascript css svg css-transitions

我有一个svg,其上设置了过渡.现在当我向它添加一个具有一些属性变化的类时,只有在DOMContentLoaded事件和addclass事件之间添加延迟时才会发生转换.这里有两个例子,第一个没有延迟第二个有无限小延迟:

不延误:

! function() {
  window.addEventListener('DOMContentLoaded', function() {
    var logo2 = document.querySelector("svg");
    logo2.classList.add('start');
  });
}();
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

延迟:

! function() {
  window.addEventListener('DOMContentLoaded', function() {
    var logo2 = document.querySelector("svg");
    setTimeout(function(){
       logo2.classList.add('start');
    },0);
  });
}();
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

正如您在第二个示例中所看到的,我添加了0秒的延迟,但它导致动画工作,为什么?

Update1:​​嗯...我们都错了:-)

我没有DOMContentLoaded和没有延迟尝试相同的代码.它仍然没有延迟添加过渡:

! function() {
 
    var logo2 = document.querySelector("svg");
    logo2.classList.add('start');

}();
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

我还注意到jQuery不会导致重排.下面是一个内联jquery代码的示例,ready在加载CSSOM之前仍然不会触发函数.如果我们有外部jquery,那么在CSSOM准备就绪之后就会触发就绪事件,而不是内联jquery.我已经达成的理解是CSSOM在渲染html dom后需要几毫秒.所以直到下载外部jquery CSSOM就准备好了.DOMContentLoaded只是不关心是否加载样式表,也就是说它不关心CSSOM是否准备就绪.

Kai*_*ido 7

因为这就是DOMContentLoaded的作用:它在解析DOM时触发,但在CSSOM之前触发(因此在应用样式之前).

如果您不想等待load事件,
一种方法是通过调用任何文档元素(例如)上的属性,强制浏览器在脚本执行(同步)之前绘制:offsetXXX<body>

! function() {
  window.addEventListener('DOMContentLoaded', function(){
    document.body.offsetTop; // force a CSS repaint
    var logo2 = document.querySelector("svg");
    logo2.classList.add('start');
  });
}();
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)