如何判断内联对象标签是否已加载其数据

时间:2019-01-12 02:33:07

标签: javascript html

我正在使用一些预先声明的<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>似乎没有任何相似之处,除非我盯着它看。

1 个答案:

答案 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,我也只能建议您使用