【问题标题】:How to execute javascript in shadow dom/web components?如何在影子 dom/web 组件中执行 javascript?
【发布时间】:2019-05-10 22:32:23
【问题描述】:

我正在尝试创建一个自定义元素,其中大部分 javascript 封装/引用在模板/html 本身中。如何从要在影子 dom 中执行的模板/元素中制作 javascript?下面是一个例子,可以更好地理解这个问题。如何让template.innerHTML (<script>alert("hello"); console.log("hello from tpl");</script>) 中的脚本执行?

目前我没有收到任何警报或登录控制台。我正在用 Chrome 进行测试。

class ViewMedia extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({mode: 'closed'});
    var template = document.createElement( 'template' );
    template.innerHTML = '<script>alert("hello"); console.log("hello from tpl")';
    shadow.appendChild( document.importNode( template.content, true ) ); 
  }
}

customElements.define('x-view-media', ViewMedia);
&lt;x-view-media /&gt;

【问题讨论】:

标签: javascript dom shadow-dom custom-element


【解决方案1】:

几点:

  1. 浏览器不再允许您通过innerHTML 添加脚本
  2. 在 DOM 中没有像 iFrame 中那样的 Web 组件的脚本沙盒。

您可以使用var el = document.createElement('script'); 创建脚本块,然后将它们添加为子元素。

class ViewMedia extends HTMLElement {
   constructor() {
      super();
      const shadow = this.attachShadow({mode: 'closed'});
      const s = document.createElement('script');
      s.textContent = 'alert("hello");';
      shadow.appendChild(s);
    }
}

customElements.define('x-view-media', ViewMedia);
&lt;x-view-media&gt;&lt;/x-view-media&gt;

【讨论】:

  • 有些库并非设计为 Web 组件类的一部分(即我使用的是空间导航库)。从 html 模板/文档而不是 Web 组件类加载脚本也会使我的代码更易于管理和更少仪式。我将尝试基于 createElement 创建一个“脚本加载器”,看看它是否有效。沙盒级别对我来说已经足够好了(即 document.querySelector 只从影子 dom 中选择元素)。
  • 你可以在页面上加载库并从 Web 组件中使用它吗??
  • 不,它不起作用。我已经试过了。此外,我希望对 Web 组件进行更多封装(即在 Web 组件本身中具有其依赖项,而不是在父组件中加载所有类型的依赖项。
  • 您甚至可能不需要 Web 组件。为什么不使用一小段脚本来生成所有需要的&lt;script&gt; 标签来嵌入您需要的所有内容。或者将所有东西都转换成相互依赖的 ES6 模块。是的,您可以在组件中加载 JS,但除非您需要组件,否则它只是开销并且与旧浏览器不兼容,除非您包含 polyfill。
  • 当然我需要一个组件...我应该如何获得 CSS 隔离?
猜你喜欢
  • 2018-09-11
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-06
  • 1970-01-01
  • 2020-03-24
  • 1970-01-01
相关资源
最近更新 更多