41

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

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

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

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

其中“chart”是嵌入元素的 id。

如果我在 html 文档准备好时尝试访问 SVG,以这种方式:

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

svg 始终为空。我只需要知道它什么时候不为空,这样我就可以开始操作它了。你知道有没有办法做到这一点?

4

8 回答 8

24

在主文档中的嵌入元素(例如“embed”、“object”、“iframe”)上添加一个onload调用您的函数的属性,或在脚本中添加事件侦听器,例如embeddingElm.addEventListener('load', callbackFunction, false). 另一种选择可能是听DOMContentLoaded,这取决于你想要它。

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

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

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

于 2010-08-18T09:19:02.947 回答
15

您可以使用onload事件进行检查。

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

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

jQuery

var svgholder = $('body').find("object#svgholder");

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

javascript

var svgholder = document.getElementById("svgholder");

svgholder.onload = function() {
    alert("some svg loaded");
}
于 2015-11-26T09:32:49.213 回答
9

假设您的 SVG 在<embed>标签中:

<embed id="embedded-image" src="image.svg" type="image/svg+xml" />

SVG 图像本质上是在一个子文档中,该子文档将具有load与主文档不同的事件document。但是,您可以侦听此事件并进行处理:

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

这比轮询要好,因为您对 SVG 所做的任何修改都将在第一次绘制之前发生,从而减少了闪烁和绘制所花费的 CPU 工作量。

于 2013-10-02T15:49:18.303 回答
5

嵌入元素(例如对象)的加载事件将是我的偏好,但如果由于某种原因这不是一个可行的解决方案,我发现的唯一通用且可靠的 SVG DOM 测试是 SVG 的 getCurrentTime 方法根元素:

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 :

返回相对于当前 SVG 文档片段的开始时间的当前时间(以秒为单位)。如果在文档时间线开始之前调用 getCurrentTime(例如,通过在调度文档的 SVGLoad 事件之前在“脚本”元素中运行的脚本),则返回 0。

于 2013-12-31T10:09:19.807 回答
2

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

$(window).load(function(){
    var svg = document.getElementById("chart").getSVGDocument();
});
于 2010-11-13T07:48:48.143 回答
0

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

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

你可以通过const svg = this.startimage.nativeElement.getSVGDocument();

于 2020-03-18T07:26:37.577 回答
-1

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

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

该事件在用户代理完全解析元素及其后代并准备好对该元素采取适当行动时触发

于 2008-12-03T14:37:32.730 回答
-4

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

function checkReady() {
    var svg = document.getElementById("chart").getSVGDocument();
    if (svg == null) {
        setTimeout("checkReady()", 300);
    } else {
        ...
    }
}
于 2008-12-03T14:53:50.810 回答