我正在使用一些预先声明的<object>
标签来加载一些SVG
<object type="image/svg+xml" data="some.svg"></object>
我想在加载该SVG之后对其进行操作。如何等待加载并确保获得加载事件。换句话说,在我有机会附加load
事件之前,我是否需要处理对象可能已经加载的情况。
这样做是在调用getSVGDocument
,如果它返回null,则添加load
事件。在Firefox和Safari上失败了。
我当前的解决方案是尝试重新加载svg以强制执行加载事件
class Waiter {
constructor() {
this.promise = new Promise((resolve) => {
this.resolve = resolve;
});
}
}
async function getSVGDocument(elem) {
const data = elem.data;
elem.data = '';
elem.data = data;
const waiter = new Waiter();
elem.addEventListener('load', waiter.resolve);
await waiter.promise;
return elem.getSVGDocument();
}
这似乎行得通,但似乎也很可怕。
还有其他方法可以判断<object>
是否已加载。显然<img>
标签具有completed
property,但<object>
似乎没有任何相似之处,除非我盯着它看。
答案 0 :(得分:1)
是的,在之后设置数据是设置浏览器的唯一跨浏览器方法。
当以下脚本有机会甚至没有解析({see this Q/A)的机会来缓存数据时,Safari就有触发此事件的坏习惯。
但是由于浏览器仍然应该使用缓存(如果服务器配置正确),因此再次设置数据并不是什么大问题。现在,如果您真的不想要,可以始终将其设置为数据属性,然后在脚本执行时才设置真正的data
属性:
obj.onload = e => console.log('loaded');
obj.data = obj.dataset.source;
<object data-source="https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg" id="obj"></object>
但是请注意,虽然看起来HTMLObjectElement旨在成为加载svg文件的最佳元素,但事实证明,由于实现起来很奇怪(至少可以这样说),您可能更喜欢使用iframe,这是一个更可靠。
例如,每次您隐藏+显示元素时,Safari和Chrome都会重新加载对象的内容。
这只是一个示例,说明它们的实现是有问题的并且可能是危险的,这也是为什么我只将其表示为a fiddle的示例。
obj.onload = e => console.log('loaded');
object:hover{ display:none; }
<object data="foo.svg" id="obj"></object>
在chrome中,只需将鼠标悬停在此
是的,即使它需要更多的CSS,我也只能建议您使用