Web组件中的路径是相对于根的
Paths in Web Components are Relative to Root
我正在使用本机实现创建一个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
)中获得该值。
因此,为了回答您的第二个问题,我认为本机实现和多填充实现没有任何区别,至少在src
和href
属性的行为方面是这样
引用您提到的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资源
- 我可以获得相对于被点击元素的确切点击位置吗
- JavaScript:单击时相对于父级增加变量值
- 打开相对于鼠标位置的CSS3/HTML5模式对话框
- 相对于角度控制器中的另一个阵列过滤阵列项目
- Javascript元素相对于屏幕的位置
- 块相对于父对象的位置
- 如果元素在容器外部,是否可以相对于容器以绝对定位来定位该元素
- 如何相对于浏览器窗口定位DIV
- 立即调用函数表达式(IIFE)相对于普通函数的优势
- 获取插入符号相对于行可见起点的位置
- 如何使Highcharts中的渲染标签始终可见,并且相对于单击或悬停的点仍然可见
- 正在获取单击的元素相对于整个文档的索引
- jQuery"悬停时放大”;无法相对于图片中心放大
- 获取相对于窗口的IFRAME位置
- 在相对于用户当前 URL 路径的不同路径中设置 Cookie
- Web组件中的路径是相对于根的
- 如何用Three.js定义一个相对于矢量路径的粒子云
- 提供给insertCS()的文件路径应该是相对于什么的
- 如何获得Grunt-Contrib-Copy来相对于给定的源路径复制文件/目录
- 相对于文件的Javascript路径