Web组件中的路径是相对于根的

Paths in Web Components are Relative to Root

本文关键字:相对于 路径 Web 组件      更新时间:2023-09-26

我正在使用本机实现创建一个web组件,在它的html模板中有到图像的链接。然而,这些链接只有在它们是绝对的或相对于主文档的情况下才起作用,这意味着该组件是不可重用或可移植的。此外,这也是非常违反直觉的。

目前,我为所有需要使用图像的元素添加了一个data-url_prefix属性。然后,在为我的自定义元素创建影子根时,我将用该参数的值替换{URL_PREFIX}}。

我的解决方案似乎很糟糕。如果你能给我一些更好的建议,我将非常高兴,谢谢。


我在http://webcomponents.org/polyfills/html-imports/页码:

POLYFILL注释

在导入的文档中,HTML中的href和src属性以及url属性,相对于导入的位置文档,而不是主文档。

为什么polifill会使用与本机实现不同的逻辑?


Web组件理想情况下应该封装它们的所有依赖项,但如果Web组件需要图像,它应该知道该图像的绝对URL,这不允许简单地在文件结构中移动组件。

例如,我有以下结构:

  • index.html
  • css
    • main.css
  • js
    • main.js
  • web组件
    • 冷却网组件
      • cool_web_component.html
      • icon.png

如果我将其更改为以下内容:

  • index.html
  • css
    • main.css
  • js
    • main.js
  • 冷却网组件
    • cool_web_component.html
    • icon.png

我需要在这些文件中的某个地方将指针更改为icon.png我的问题是如何避免它,或者以优雅的方式解决它。此外,为什么实际的本机实现与polyfill冲突?

Web组件规范定义URL始终相对于主文档。当然,这破坏了web组件封装,正如您正确地总结的那样。换句话说,这个规范有缺陷,很多人都在抱怨。这就是为什么polyfill没有遵循规范:它正在解决问题。

规格将会更改。然而,由于这不是微不足道的修复,它仍然可能需要一些时间。请查看以下链接:

•https://lists.w3.org/Archives/Public/public-webapps/2014OctDec/0013.html

•https://www.w3.org/Bugs/Public/show_bug.cgi?id=20976#c8

目前,解决方案是您的组件将其模板图像的URL从相对更改为绝对。您可以按如下方式获得templateBaseUrl

(function (window, document)
    {
    var proto = Object.create(HTMLElement.prototype);
    var template = document.currentScript.ownerDocument.querySelector("template");
    var templateBaseUrl = template.baseURI;
    proto.createdCallback = function ()
        {
        // Now find all images inside the template and change their src attribute, 
        // using templateBaseUrl. Also you must change CSS background-image: url(...);
        ...
        };
    document.registerElement('test-element', {prototype: proto});
    })(window, document);

在像图标这样的小图像的情况下,另一种解决方法是使用数据URI将图像数据直接嵌入到文档中。这也保存了HTTP请求(直到我们有了HTTP/2)。例如:

<img src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" />

这种行为似乎是图像特有的
对于脚本和链接标记,导入文档的相对路径可以按预期工作。

我还注意到,这并不是polyfill特有的东西,即使对于本机实现(chrome),这个问题(?)似乎也存在。

似乎这里唯一的选择是在导入的html中包含一个脚本,它将把这些相对路径转换为它们的绝对对应路径
为了优雅地解决这个问题,您可以避免在脚本中对url进行硬编码,并使用导入文档的url生成它。您可以从document.currentScript.ownerDocument(或在多填充场景中的document._currentScript.ownerDocument)中获得该值。

因此,为了回答您的第二个问题,我认为本机实现和多填充实现没有任何区别,至少在srchref属性的行为方面是这样
引用您提到的http://webcomponents.org/polyfills/html-imports/似乎是特定于脚本和链接标记的href/src的,它们按照编写的方式工作。

希望能有所帮助。

根据我之前对MarcG答案的评论做出回应-模块需要知道自己的路径,这一点已经得到了认可,现在可以通过import.meta.url平均值来检索!

因此,现在编写一些util来获取组件的HTML/CSS要容易得多。

此外,如果CSS不是提取的,而是动态添加到文档中的一个新样式表链接,那么这个CSS在相关路径方面表现得非常好。

有了这一点,今天,在等待某种标准方法来指定我的组件的基本url时,我的ow方法是为一个组件提供2个资源:

  • 主/单个HTML通过fetch API获取,转换为模板,缓存,然后在每次新的组件实例附加到DOM时克隆到组件中
  • 主CSS由标准link元素链接
  • 这两个文件的名称与提供组件类的主JS文件的名称相同,这使得将整个混乱变成十几行util更容易
  • 如果需要,在主CSS中添加额外的CSS资源作为常规的相对导入
  • 如果可能的话,使用相对导入将图像添加为url背景
  • 显然只不过是一个HTML资源