为什么不立即转换在DOMContentLoaded上的svg工作? [英] Why don't transitions on svg work on DOMContentLoaded without delay?

查看:105
本文介绍了为什么不立即转换在DOMContentLoaded上的svg工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个svg,它设置了转换。现在,当我添加一个具有不同属性的类时,只有在DOMContentLoaded事件和addclass事件之间添加延迟时才会发生转换。这里有两个例子,第一个没有延迟,其次是无限小延迟:



不带延迟: data-lang =jsdata-hide =falsedata-console =truedata-babel =false>

 ! function(){window.addEventListener('DOMContentLoaded',function(){var logo2 = document.querySelector(svg); logo2.classList.add('start');});}();  

 < svg xmlns =http://www.w3.org/ 2000 / svgviewBox =0 0 104.75 32.46> < DEFS> <风格>多边形{fill:red;过渡:不透明3s缓解,3s缓解;不透明度:0; } .start polygon {opacity:1; }#A1 polygon {transform:translate(100px,100px);转换延迟:1s; } / *动画开始后的样式* / .start#A1多边形{transform:translate(0px,0px); }< / style> < / DEFS> <标题>标志< /标题> < g id =A1> < polygon class =rightpoints =0.33 31.97 0.81 26.09 13.61 3.84 13.13 9.72 0.33 31.97/> < / g取代; < / svg>  

$ b


$ b

! function(){window.addEventListener('DOMContentLoaded',function(){var logo2 = document.querySelector(svg); setTimeout(function(){logo2.classList.add('start');},0); }};}();

< svg xmlns = http://www.w3.org/2000/svgviewBox =0 0 104.75 32.46> < DEFS> <风格>多边形{fill:red;过渡:不透明3s缓解,3s缓解;不透明度:0; } .start polygon {opacity:1; }#A1 polygon {transform:translate(100px,100px);转换延迟:1s; } / *动画开始后的样式* / .start#A1多边形{transform:translate(0px,0px); }< / style> < / DEFS> <标题>标志< /标题> < g id =A1> < polygon class =rightpoints =0.33 31.97 0.81 26.09 13.61 3.84 13.13 9.72 0.33 31.97/> < / g取代; < / svg>



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



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



我没有延迟地尝试过没有 DOMContentLoaded 的相同代码。它仍然不会没有延迟地添加转换:

< svg xmlns =http://www.w3.org/2000/svgviewBox =0 0 104.75 32.46> < DEFS> <风格>多边形{fill:red;过渡:不透明3s缓解,3s缓解;不透明度:0; } .start polygon {opacity:1; }#A1 polygon {transform:translate(100px,100px);转换延迟:1s; } / *动画开始后的样式* / .start#A1多边形{transform:translate(0px,0px); }< / style> < / DEFS> <标题>标志< /标题> < g id =A1> < polygon class =rightpoints =0.33 31.97 0.81 26.09 13.61 3.84 13.13 9.72 0.33 31.97/> < / g取代; < / svg>

我还注意到jQuery没有引起回流。下面是内联jQuery代码的示例,在加载CSSOM之前,它仍然不会触发 ready 函数。如果我们有外部jquery,而不是内联jquery,那么准备就绪事件会在CSSOM准备就绪后触发。我已经达到的理解是,CSS DOM需要几毫秒后呈现html dom。所以直到下载外部jQuery CSSOM准备就绪。 DOMContentLoaded 根本不在乎是否加载样式表,也就是说不关心CSSOM是否准备好。

解决方案

因为这就是 DOMContentLoaded 的确如此:它在DOM被解析之后,但在CSSOM之前(因此在应用样式之前)触发。

If您不希望等待加载事件,

的一种方式是将浏览器强制为 通过在任何文档的元素(例如< body> ):


! function(){window.addEventListener('DOMContentLoaded',function(){document.body.offsetTop; //强制一个CSS重绘var logo2 = document.querySelector(svg); logo2.classList.add('start') ;}();

< svg xmlns =http://www.w3.org/2000/svgviewBox =0 0 104.75 32.46> < DEFS> <风格>多边形{fill:red;过渡:不透明3s缓解,3s缓解;不透明度:0; } .start polygon {opacity:1; }#A1 polygon {transform:translate(100px,100px);转换延迟:1s; } / *动画开始后的样式* / .start#A1多边形{transform:translate(0px,0px); }< / style> < / DEFS> <标题>标志< /标题> < g id =A1> < polygon class =rightpoints =0.33 31.97 0.81 26.09 13.61 3.84 13.13 9.72 0.33 31.97/> < / svg>


I have an svg with transitions set on it. Now when I add a class to it which has some properties varied then the transition only occur if I add delay between DOMContentLoaded event and addclass event. Here are two example, first with no delay second with an infinitesmall delay:

Without Delay:

! function() {
  window.addEventListener('DOMContentLoaded', function() {
    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>

With Delay:

! function() {
  window.addEventListener('DOMContentLoaded', function() {
    var logo2 = document.querySelector("svg");
    setTimeout(function(){
       logo2.classList.add('start');
    },0);
  });
}();

<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?

Update1: well... we all are wrong :-)

I tried the same code without DOMContentLoaded and without delay. It still doesn't add transition without a delay:

! function() {
 
    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>

I also noted that jQuery doesn't cause a reflow. Here is an example of inline jquery code that still doesn't fire ready function before CSSOM is loaded. Instead of inline jquery if we had external jquery then ready event would fire after CSSOM is ready. The understanding I have reached is that CSSOM needs a few milliseconds after html dom is rendered. So till it downloads external jquery CSSOM is ready. DOMContentLoaded simply don't care if stylesheets are loaded or not, that is it doesn't care if CSSOM is ready or not.

解决方案

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>

这篇关于为什么不立即转换在DOMContentLoaded上的svg工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆