如何检查嵌入式SVG文档是否加载到html页面?

ale*_*eia 33 javascript jquery svg dom

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

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

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

var svg = document.getElementById("chart").getSVGDocument();
Run Code Online (Sandbox Code Playgroud)

其中"chart"是embed元素的id.

如果我在html文档准备就绪时尝试访问SVG,这样:

jQuery(document).ready( function() {
var svg = document.getElementById("chart").getSVGDocument();
...
Run Code Online (Sandbox Code Playgroud)

svg始终为null.我只需要知道它何时不为空,所以我可以开始操纵它.你知道有没有办法做到这一点?

Eri*_*röm 22

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

您还可以在主文档上添加加载侦听器.jQuery(document).ready并不意味着所有资源都被加载,只是文档本身有一个可以采取行动的DOM.但是请注意,如果你在整个文档上监听加载,那么在加载该文档中的所有资源,css,javascript等之前,不会调用回调函数.

如果你使用内联svg,那么jQuery(document).ready将工作得很好.

另外请注意,您可能需要考虑使用embeddingElm.contentDocument(如果可用)而不是embeddingElm.getSVGDocument().

  • 如果在脚本运行时已经加载了embeddingElm,embeddingElm.addEventListener('load',callbackFunction,false)将不起作用.如果链接SVG中的图像(如背景图像),DOMContentLoaded将不起作用.你(不应该)想要这样做:类似于:window.onload,因为那时你必须等到所有外部资源都被下载(例如跟踪脚本和广告) (2认同)

Ros*_*yal 11

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

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

<body>    
<object id="svgholder" data="some.svg" type="image/svg+xml"></object>
</body>
Run Code Online (Sandbox Code Playgroud)

jQuery的

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

svgholder.load("image/svg+xml", function() {
    alert("some svg loaded");
});
Run Code Online (Sandbox Code Playgroud)

JavaScript的

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

svgholder.onload = function() {
    alert("some svg loaded");
}
Run Code Online (Sandbox Code Playgroud)

  • `svgholder.load("image/svg+xml", function()...` 似乎是调用 jquery ajax 加载。在 v3.0 之前,jquery 根据提供的参数确定要调用哪个加载。第一个参数中的字符串,jquery 尝试将“image/svg+xml”作为 url 执行 GET。由于它将加载的内容放置在所选元素中,然后调用提供的回调,因此这可能看起来像加载的通知,但它正在做其他事情。在控制台中查找 404。此外,从 3.0 开始不推荐使用 .load 事件处理程序。 (2认同)

Dre*_*kes 8

假设你的SVG在一个<embed>标签中:

<embed id="embedded-image" src="image.svg" type="image/svg+xml" />
Run Code Online (Sandbox Code Playgroud)

SVG图像基本上位于子文档中,该子文档将具有load与main 的单独事件document.但是,您可以侦听此事件并处理它:

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

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


小智 6

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

\n\n
var element = document.getElementById( \'elementId\' );\nvar svgDoc = element.contentDocument;\nvar svgRoot = svgDoc ? svgDoc.rootElement : null;\n\nif ( svgRoot\n    && svgRoot.getCurrentTime\n    && ( svgRoot.getCurrentTime() > 0 ))\n{\n    /* SVG DOM ready */\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

W3C SVG 建议规定 SVGSVGElement 上的 getCurrentTime:

\n\n
\n

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

\n
\n


Moc*_*cky -4

您可以尝试经常进行轮询。

function checkReady() {
    var svg = document.getElementById("chart").getSVGDocument();
    if (svg == null) {
        setTimeout("checkReady()", 300);
    } else {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 轮询并不是执行此操作的好方法。请改用“load”事件侦听器。 (23认同)