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

标签 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>除非我直视它,否则似乎没有任何类似的东西。

最佳答案

是的,在设置加载处理程序之后再次设置数据是处理此问题的唯一跨浏览器方法。
Safari 有一个非常坏的习惯,即在以下脚本有机会解析 ( see this Q/A ) 之前缓存数据时触发此事件。

但是由于浏览器无论如何都应该使用缓存(如果您的服务器配置良好),因此再次设置数据并不是什么大问题。现在,如果您确实不想,您始终可以先将其设置为数据属性,然后当您的脚本执行时,您才会设置真正的 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,我也只能建议你使用 <iframe> 来代替。

关于javascript - 如何判断内联对象标签是否已加载其数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54156309/