关于javascript:如何检查HTML页面中是否加载了嵌入式SVG文档?

How to check if an embedded SVG document is loaded in an html page?

我需要编辑(使用javascript)嵌入html页面的SVG文档。

加载SVG后,我可以访问SVG的dom及其元素。 但是我不知道SVG dom是否准备好,因此在加载html页面时,我无法对SVG执行默认操作。

要访问SVG dom,我使用以下代码:

1
var svg = document.getElementById("chart").getSVGDocument();

其中"图表"是embed元素的ID。

如果在html文档准备好后尝试访问SVG,则采用这种方式:

1
2
3
jQuery(document).ready( function() {
var svg = document.getElementById("chart").getSVGDocument();
...

svg始终为null。 我只需要知道它何时不为null,就可以开始对其进行操作了。
您知道是否有办法吗?


在主文档的嵌入元素(例如'embed','object','iframe')上,添加一个onload属性来调用您的函数,或者在脚本中添加事件监听器,例如embeddingElm.addEventListener('load', callbackFunction, false)。另一个选择可能是监听DOMContentLoaded,具体取决于您想要的是什么。

您还可以在主文档上添加一个加载侦听器。 jQuery(document).ready并不意味着所有资源都已加载,仅意味着文档本身具有一个可供操作的DOM。但是请注意,如果您侦听整个文档的加载,则只有在加载该文档中的所有资源,css,javascript等之后,才会调用回调函数。

如果您使用内联svg,则jQuery(document).ready将可以正常工作。

进一步说明,您可能要考虑使用embeddingElm.contentDocument(如果可用)而不是embeddingElm.getSVGDocument()


You could use an onload event for the check.

假设some.svg嵌入在对象标签中:

1
2
3
<body>    
<object id="svgholder" data="some.svg" type="image/svg+xml"></object>
</body>

jQuery的

1
2
3
4
5
var svgholder = $('body').find("object#svgholder");

svgholder.load("image/svg+xml", function() {
    alert("some svg loaded");
});

javascript

1
2
3
4
5
var svgholder = document.getElementById("svgholder");

svgholder.onload = function() {
    alert("some svg loaded");
}


假设您的SVG位于标记中:

1
 

SVG映像本质上位于子文档中,该子文档将具有与主document事件分开的load事件。但是,您可以侦听并处理此事件:

1
2
3
4
5
6
var embed = document.getElementById("embedded-image");
embed.addEventListener('load', function()
{
    var svg = embed.getSVGDocument();
    // Operate upon the SVG DOM here
});

这比轮询更好,因为您对SVG所做的任何修改都将在首次绘制之前进行,从而减少了闪烁和CPU工作量。


我首选使用嵌入元素(例如,对象)的load事件,但是,如果由于某种原因这不是可行的解决方案,那么我找到的针对SVG DOM的唯一通用且可靠的测试就是SVG的getCurrentTime方法根元素:

1
2
3
4
5
6
7
8
9
10
var element = document.getElementById( 'elementId' );
var svgDoc = element.contentDocument;
var svgRoot = svgDoc ? svgDoc.rootElement : null;

if ( svgRoot
    && svgRoot.getCurrentTime
    && ( svgRoot.getCurrentTime() > 0 ))
{
    /* SVG DOM ready */
}

W3C SVG建议指出SVGSVGElement上的getCurrentTime:

Returns the current time in seconds relative to the start time for the current SVG document fragment. If getCurrentTime is called before the document timeline has begun (for example, by script running in a ‘script’ element before the document's SVGLoad event is dispatched), then 0 is returned.


使用jQuery可以绑定到Erik提到的窗口加载事件:

1
2
3
$(window).load(function(){
    var svg = document.getElementById("chart").getSVGDocument();
});


供将来参考:Angular(8)/ Typescript解决方案如下所示:

1
2
3
4
5
6
  @ViewChild('startimage', {static:false})
  private startimage: ElementRef;
...
  this.startimage.nativeElement.addEventListener('load', () => {
    alert('loaded');
  });

您可以通过const svg = this.startimage.nativeElement.getSVGDocument();进入svg


您可以为SVG文档中的元素分配onload事件处理程序,并使其在html页面中调用javascript函数。 onload映射到SVGLoad。

http://www.w3.org/TR/SVG11/interact.html#LoadEvent

The event is triggered at the point at which the user agent has fully parsed the element and its descendants and is ready to act appropriately upon that element


您可以尝试每隔一段时间进行一次轮询。

1
2
3
4
5
6
7
8
function checkReady() {
    var svg = document.getElementById("chart").getSVGDocument();
    if (svg == null) {
        setTimeout("checkReady()", 300);
    } else {
        ...
    }
}