我正在使用本机实现创建一个Web组件,该组件的html模板中包含指向图像的链接。 但是,这些链接仅在绝对或相对于主文档时才起作用,这意味着该组件不可重用或可移植。而且,这非常违反直觉。
目前,我将data-url_prefix属性添加到需要使用图像的所有元素。然后,在为自定义元素创建阴影根时,我将{{URL_PREFIX}}替换为该参数的值。
我的解决方案似乎很糟糕。如果你建议更好的话,我会很高兴,谢谢。
我在http://webcomponents.org/polyfills/html-imports/页面上找到了一个有趣的引语:
POLYFILL NOTES
在导入的文档中,HTML和url中的href和src属性 CSS文件中的属性,是相对于导入的位置 文件,而不是主要文件。
为什么polifill会使用与本机实现不同的逻辑?
Web组件理想情况下应该封装它们的所有依赖项,但是如果Web组件需要图像,它应该知道该图像的绝对URL,这不允许在文件结构中简单地移动组件。
比如说,我有以下结构:
如果我将其更改为以下内容:
我需要在这些文件中的某处更改指向icon.png的指针 我的问题是如何避免它,或以优雅的方式解决它。另外,为什么实际的原生实现与polyfill冲突?
答案 0 :(得分:6)
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" />
答案 1 :(得分:1)
此行为似乎特定于图像 对于脚本和链接标记,导入文档的相对路径按预期工作。
另外我注意到这不是polyfills特有的东西,即使对于本机实现(chrome)这个问题(?)似乎也存在。
这里似乎唯一的选择是在导入的html中包含一个脚本,它会将这些相对路径转换为绝对路径。
为了优雅地解决它,您可以避免在脚本中硬编码网址并使用导入文档的网址生成网址。您可以从document.currentScript.ownerDocument
(或填充方案中的document._currentScript.ownerDocument
)获取该内容。
因此,为了回答您的第二个问题,至少在src
和href
属性的行为方面,我发现原生和多种填充实施方式没有任何差异。
你在http://webcomponents.org/polyfills/html-imports/中提到的引用似乎特定于脚本和链接标记的href / src,它们的工作方式也是如此。
希望它有所帮助。
答案 2 :(得分:0)
根据我对MarcG答案的先前评论-认识到模块知道自己的路径的必要性,如今,import.meta.url
的意思可能可以找回模块!
因此,现在编写一些实用程序来获取组件的HTML / CSS变得容易得多。
此外,如果未获取CSS,而是向文档动态添加了一个新的样式表链接,则此CSS在相对路径上的表现也很好。
今天,在等待某种标准方法指定组件的基本URL的同时,我的ow方法是为组件提供2种资源:
fetch
API提取主要/单个HTML,将其转换为模板,进行缓存,然后在每次将新实例附加到DOM时将其克隆到组件中link
元素