Shadow DOM:是否可以封装JS?

问题描述 投票:0回答:3

我正在尝试找到一种不使用 iframe 来封装 Javascript 的方法。理想情况下,我想要一种在父页面上加载外部 HTML 组件(小部件)的方法,而不需要使用 iframe 附带的两步加载过程(首先加载主机页面,然后才加载 iframe 内容) )。

是否可以使用一些新的 Web 组件技术(shadow DOM / 模板 / 导入)来实现这一点?我能够接近将 HTML 添加到 Shadow DOM 并封装 CSS,但无法确认是否可以为组件的 javascript 执行获取单独的文档。

javascript html iframe web-component shadow-dom
3个回答
6
投票

Web 组件,通过 HTML 导入 使用,封装 Shadow DOM HTML 相关脚本。

为了缩小术语范围,我们假设我们有一个聚合物组件core-ajax。这是代码。正如您可能看到的,它根本不提供任何 HTML 标记,仅封装 脚本

在主机网页上导入后:

<link 
  rel="import"
  href="https://www.polymer-project.org/components/core-ajax/core-ajax.html"> 

该组件提供了无需任何 JavaScript 编码即可执行 AJAX 调用的能力:

<core-ajax
  auto
  url="http://gdata.youtube.com/feeds/api/videos/"
  params='{"alt":"json", "q":"chrome"}'
  handleAs="json"
  response='{{response}}'
</core-ajax>

上面将加载(因为设置了

auto
属性)指定 URL 的内容并将响应放入绑定的
response
变量中。与此组件通信的另一种方法是提供处理程序,而不是将模板变量绑定到响应:

  - response='{{response}}'
  + on-core-response="{{handleResponse}}"

可以在页面的 javascript 中实现

handleResponse
函数,仅此而已。

UPD 虽然目前无法区分主文档和影子 DOM 使用的文档,但这一功能在 w3c 邮件组中已经讨论了近三年。不过,即使在“我们是否从未在作者空间中完全启用它们”等方面,讨论还远未结束。


2
投票
这与shadow dom无关,但与完全使用javascript封装组件有关:

https://benfrain.com/sandbox-local-htmlcss-code-snippets-inside-iframe-style-guidespattern-libraries /

基本上,您创建一个 iframe 节点并向其中注入 css 和 javascript:

var newIframe = document.createElement('iframe') newIframe.contentWindow.document.open('text/html', 'replace') var content = '<!DOCTYPE html><html><head>'+CSS+'</head><body>'+HTML+JS+'</body></html>' newIframe.contentWindow.document.write(content) newIframe.contentWindow.document.close()

要完全隔离 javascript 访问其父页面,我相信您可以使用某种随机生成的域修改父页面的

document.domain

 ,这样,对于新的 iframe,父页面看起来就像在不同的域中,并且无法更改其域以匹配。这将伴随所有常见的安全限制。然后你就可以通过 postmessage 安全地与子 iframe 对话。 

理论上,您还可以实现一些通信来根据 iframe 元素的内容自动调整其大小,模拟非 iframe 元素流入。

这是我以后想尝试的,但还没有尝试过。


0
投票
是的,您可以在模板内添加

<style>

<script>
 标签(代码片段仅在支持 Shadow DOM 的浏览器中运行):

// Create the shadow DOM var shadow = document.querySelector('#testOutput').attachShadow({mode: 'open'}); // Get the template fragment and add it to the shadow DOM shadow.appendChild(document.querySelector('#testTemplate').content);
<template id="testTemplate">
  <script>
    alert('Hello from the component');
  </script>
</template>

<div id="testOutput">shadow</div>

或者您可以将它们直接添加到 Shadow DOM。

但是,这

目前已被内容安全策略所破坏,并且存在很高的 XSS 风险

© www.soinside.com 2019 - 2024. All rights reserved.