在 iframe 中创建自定义元素

create custom elements in iframe

由于 html 导入还没有得到很好的支持(例如,Firefox 没有计划这样做),我试图模仿它在通过 iframes 导入自定义元素时的使用。

我尝试这样做的方法是在 iframe 中加载一个脚本,该脚本在顶部浏览上下文中定义自定义元素;之后甚至可以从文档中删除 iframe。我尝试这样做的原因是因为我想根据我在客户端获得的信息动态定义自定义元素;这些自定义元素使用模板在阴影中使用 DOM.

我更喜欢使用模板而不是在脚本中构建影子 DOM 以获得干净的代码;这就是为什么我想用带有所有模板的 iframe 来模拟导入功能,而不是仅仅加载构建阴影 DOM 的脚本。

但是,我试过的方法不起作用(在 google chrome 和 firefox 中测试):

// iframe.js

class XAElement extends HTMLElement{
 constructor(){
  super()
  // Any customization here
 }
 // Any other methods for functionality
}
top.customElements.define('x-a', XAElement)

是否允许在 iframe 中定义顶部浏览上下文的自定义元素?

注意:文件iframe.html是任何加载此脚本的html文件;并且文件 index.html(发生错误的文件)是加载 iframe iframe.html.

的任何文件

注2:我得到的错误是在super()之后;但是,如果我注释最后一行(我打算在其中定义自定义元素),则不会发生错误。

如果你想模仿 HTML导入你最好使用Github repository.[=17中提供的HTMLImports.min.js库=]

<script src="htmlimports.min.js"></script>

请注意,HTML 导入本机支持 Chrome 将在下一个版本(版本 73)中删除,因为 Mozilla 和 Apple 未就 [=37= 提出的此功能达成共识]...但是上面的库仍然可以作为一个简单的 HTML 加载器工作。


或者,您可以使用 fetch() 加载 HTML 内容,如 post 关于 中所述。


如果您仍想使用 <iframe> 元素来加载 HTML 文件,您需要等待文件加载完毕才能访问其内容。

<iframe src="XA.html" onload="defineXA()"></iframe>

我认为这不是一个好的做法,因为它会创建无用的浏览上下文。

经过多次修改脚本测试,发现HTMLElementtop.HTMLElement不一样。这就是为什么从 HTMLElement 继承不适用于定义自定义元素,因为它只允许从定义自定义元素的浏览上下文中的 HTMLElement 继承。

然后,修改脚本为:

// iframe.js

class XAElement extends top.HTMLElement{
 constructor(){
  super()
  // Any customization here
 }
 // Any other methods for functionality
}
top.customElements.define('x-a', XAElement)

它最终起作用了。

我会这样做是因为,在定义自定义元素并在构造函数中保存所需的模板内容后 class(作为属性,可以在定义自定义元素之前完成),我可以删除框架。这样,我只需要加载 iframe;等待满足这些要求;并删除 iframe 以(我认为)恢复创建嵌套浏览器内容对性能的影响。

注意:如果在加载要使用的模板之前执行脚本,则在构造函数中保存模板内容应放在加载事件侦听器中。

版本:

我忘记测试如果我在发布答案时删除 iframe 会发生什么。发生的事情是它停止工作;这就是为什么我接受另一个答案。

老实说,我会避免尝试使用 HTML 导入来加载 Web 组件。它已被弃用,并将从所有浏览器中删除。

而是开始使用 ES6 模块,甚至只创建传统的 JavaScript 文件。

有很多方法可以将模板打包成 JS 文件,包括 component-build-tools 或 Webpack 或其他东西。

我的建议是停止使用死技术并转换为当前的模块加载范例。