【问题标题】:Paths in Web Components are Relative to RootWeb 组件中的路径是相对于根目录的
【发布时间】:2016-01-31 23:54:09
【问题描述】:

我正在使用本机实现创建一个 Web 组件,它的 html 模板中包含指向图像的链接。 但是,这些链接仅在它们是绝对的或相对于主文档时才有效,这意味着该组件不可重用或不可移植。此外,这是非常违反直觉的。

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

我的解决方案似乎很糟糕。如果您提供更好的建议,我将非常高兴,谢谢。


我在http://webcomponents.org/polyfills/html-imports/ 页面上发现了一个有趣的引述:

填充注释

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

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


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

比如说,我有以下结构:

  • index.html
  • CSS
    • main.css
  • js
    • main.js
  • web_components
    • cool_web_component
      • cool_web_component.html
      • icon.png

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

  • index.html
  • CSS
    • main.css
  • js
    • main.js
  • cool_web_component
    • cool_web_component.html
    • icon.png

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

【问题讨论】:

  • 你能再解释一下吗?你的意思是如果有结构 root->some_folder->image 并且你的 php 是 root->athor_folder->php_file.php 你想在 php_file.php 添加一个 img 标签来引用图像文件夹中的图像?
  • @Laurentiu,看看我的编辑,我希望它能澄清你的不理解。
  • 你可以使用像你的 js 这样的图像文件夹,并且你的绝对路径总是相同的,这意味着在你的 html 中你永远不需要使用相对路径并且你的组件是可移植的。可能 POLYFILL 会做一些事情,比如在 symfony 中重写 css,在 symfony 中也使用图像的相对路径,并且在资产 symfony 将其转换为根文件夹的绝对路径之后。我不是 POLYFILL 方面的专家,但希望这会有所帮助。

标签: javascript html polymer web-component custom-element


【解决方案1】:

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

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

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

所以要回答您的第二个问题,至少在 srchref 属性的行为方面,我认为本机和 polyfill 实现没有任何区别。
您在http://webcomponents.org/polyfills/html-imports/ 中提到的引用似乎特定于脚本和链接标签的 href/src,它们按书面形式工作。

希望对你有帮助。

【讨论】:

    【解决方案2】:

    webcomponent 规范定义 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 还会使加载的 js 文件中的任何 XHR 保持不变,这使得行为变得怪异。
    • 虽然此解决方案(检索当前脚本的基本 URL 并构建 WebComponent 其余资源的 URL)是最正确的解决方案(当然,在对相对路径的本机支持之后)但它不起作用如果组件的脚本本身是 ES6 模块,那么硬编码的绝对路径是不可避免的,可移植性是不可能的等等。
    【解决方案3】:

    对我自己对 MarcG 答案的上一个评论做出反应 - 模块需要了解自己的路径已经得到承认,现在可以通过 import.meta.url 的意思来检索!

    所以现在编写一些工具来获取组件的 HTML/CSS 会容易得多。

    此外,如果未获取 CSS,但将新样式表链接动态添加到文档中 - 此 CSS 还可以很好地与相对路径配合使用。

    既然如此,今天,在等待一些标准方法来指定我的组件的基本 url 时,我的方法是为组件提供 2 个资源:

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

    【讨论】:

      猜你喜欢
      • 2011-05-27
      • 2011-12-19
      • 2017-03-24
      • 1970-01-01
      • 2019-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多