【问题标题】:Images created using `document.currentScript.ownerDocument.createElement` (from within <link> imported HTML) never load使用 `document.currentScript.ownerDocument.createElement` (从 <link> 导入的 HTML 中)创建的图像永远不会加载
【发布时间】:2018-09-15 12:42:25
【问题描述】:

这是一个返回图像宽度的函数,给定图像的 url:

async function getImageWidthByUrl(imgUrl) {
  const imgEl = document.createElement("img");
  let untilImgLoaded = new Promise((resolve, reject) => {
    imgEl.onload = resolve;
    imgEl.onerror = reject;
  });
  imgEl.src = imgUrl;
  await untilImgLoaded;
  return imgEl.naturalWidth;
}

它工作正常。如果我们使用new Image() 而不是document.createElement("img"),它也(当然)有效。

但是,如果document 引用&lt;link&gt; html 导入的文档对象,document.createElement("img") 方法不起作用

看看this example,它导入了this html。注意控制台输出:

"Starting..."
512
512

并且永远不会输出最终的512,然后是"Finished.",就像(似乎)应该的那样。那是因为imgElonload 事件永远不会触发;如果图像是用document.currentScript.ownerDocument.createElement 创建的,它永远不会加载。我已经在 Chrome 69 中对此进行了测试。

这是预期的行为,还是错误?如果无法使用&lt;link&gt;document 创建图像,它至少不应该抛出错误吗?

【问题讨论】:

  • Firefox 似乎根本没有为 &lt;link&gt; 运行 HTTP 请求。
  • ...并且 MDN 文档没有提到“import”作为“rel”属性的公认值。
  • @Pointy Firefox 尚未实现导入(并且在当前状态下可能不会这样做)。我应该提到这一点(并且可能添加了 chrome 标签)。您需要添加 polyfill 以在 firefox 上进行测试(我尝试过,但也无法使用它)。关于它似乎工作正常的事实,我似乎不小心链接到了旧版本。我已经更新了链接,可以肯定的是:jsbin.com/kuruluzike/2/edit?html,console 如果那是你的,请删除关闭投票。
  • 并且要明确一点:我完全可以使用new Image() 来解决这个问题,但我只是好奇它是否是铬错误。这不是“请为我调试代码”的问题。

标签: javascript google-chrome web-component custom-element html5-import


【解决方案1】:

这是正常行为。

在带有&lt;link rel="import"&gt; 的导入文档中src 属性&lt;img&gt; 元素中引用的图像在附加到主文档之前不会加载。

来自HTML Imports tutorial

在您调用其服务之前,请将内容视为惰性。 [...]

除非您将其内容附加到 DOM,否则它是无操作的。实际上,唯一直接在导入文档中“执行”的就是&lt;script&gt;

您可以使用document.apendNode() 将其附加到主文档。

另外,请注意,在您的示例中,您应该将导入的文档引用作为 simple-test.html 的主函数的参数传递,原因解释为 in this postthat post

( function( ownerDocument ) {
    //...
    if( method === "document.currentScript.ownerDocument.createElement") {
        imgEl = ownerDocument.createElement("img")
        var imgOK = document.adoptNode( imgEl )
    }
    //...  
} ) ( document.currentScript.ownerDocument )

【讨论】:

  • 啊,我明白了。有趣的是new Image() 的行为不同——但我想这确实有点道理。在某些情况下,您可能不希望它在实际附加之前加载。这在规范中的任何地方都有说明吗?我将添加另一个答案 here 以帮助其他人解决此问题。
  • 嗯,你能澄清一下你在编辑中的意思吗?我们在这里谈论的是哪个主要功能?你的意思是HTML导入脚本的最后一行应该是... })(window, document.currentScript.ownerDocument);而不是... })(window, document);?谢谢!
  • @Joe 我在规范中找不到解释,但在教程中(添加了链接)。对于您的第二条评论:是的,我已经更新了答案并添加了另一个链接。
  • 太棒了!感谢您的研究!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多