在iframe中创建自定义元素

时间:2019-02-17 07:19:00

标签: javascript html5 iframe custom-element

由于尚未很好地支持html导入(例如,Firefox没有计划这样做),所以我试图模仿它在通过iframe导入自定义元素中的用法。

我尝试这样做的方法是在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()后出现错误;但是,如果我注释了最后一行(我打算在其中定义自定义元素),则不会发生错误。

3 个答案:

答案 0 :(得分:1)

如果要模仿 HTML导入,最好使用Github repository中提供的HTMLImports.min.js库。

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

请注意,Chrome浏览器中的HTML Imports本机支持将在下一个版本(版本73)中删除,因为Mozilla和Apple在Google提出的此功能上未达成共识...但是上述库仍然可以简单地工作HTML加载程序。


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


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

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

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

答案 1 :(得分:1)

多次修改脚本进行测试后,我意识到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)

它最终可以工作。

我将采用这种方式,因为在定义了自定义元素并将所需的模板内容保存在构造函数类中之后(作为属性,可以在定义自定义元素之前完成),然后删除iframe。这样,我只需要加载iframe;等待这些要求得到满足;并删除iframe,以(恢复我认为)恢复创建嵌套浏览器内容的性能影响。

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

版本:

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

答案 2 :(得分:0)

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

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

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

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