【问题标题】:create custom elements in iframe在 iframe 中创建自定义元素
【发布时间】:2019-02-17 07:18:59
【问题描述】:

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

我尝试这样做的方法是在 iframe 中加载一个脚本,该脚本在顶部浏览上下文中定义自定义元素;之后甚至可以从文档中删除 iframe。我尝试这样做的原因是因为我想根据我在客户端获得的信息动态定义自定义元素;并且那些自定义元素使用要在 shadow 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();但是,如果我注释最后一行(我打算在其中定义自定义元素),则不会发生错误。

【问题讨论】:

  • 您尝试在 iframe 上下文中声明自定义元素类,但您在顶部容器中定义了自定义元素,这是一个不同的 javascript 上下文。为什么不在 iframe 上下文中定义自定义元素?
  • @Supersharp,如果我在 iframe 浏览上下文中定义自定义元素,则自定义元素在顶部浏览上下文中不起作用。

标签: javascript html iframe custom-element


【解决方案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】:

    如果你想模仿 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 的帖子所述。


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

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

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

    【讨论】:

    • 好的,我想我会采用这种方法。但是,在这样做之前,我想了解为什么我不能使用在 iframe 浏览上下文中定义的类来定义顶部浏览上下文中的自定义元素。顺便说一句,我计划在它完成所有必须做的事情后删除 iframe 浏览上下文;它仍然会影响性能吗?
    • @RaúlArturoChávezSarmiento 因为 Javascript 代码只能在其上下文中执行,但我想你是自己找到的
    【解决方案3】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 2019-09-23
      • 2022-01-23
      • 2020-11-13
      • 1970-01-01
      • 2016-12-31
      • 1970-01-01
      相关资源
      最近更新 更多