我正在尝试找到一种不使用 iframe 来封装 Javascript 的方法。理想情况下,我想要一种在父页面上加载外部 HTML 组件(小部件)的方法,而不需要使用 iframe 附带的两步加载过程(首先加载主机页面,然后才加载 iframe 内容) )。
是否可以使用一些新的 Web 组件技术(shadow DOM / 模板 / 导入)来实现这一点?我能够接近将 HTML 添加到 Shadow DOM 并封装 CSS,但无法确认是否可以为组件的 javascript 执行获取单独的文档。
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 邮件组中已经讨论了近三年。不过,即使在“我们是否从未在作者空间中完全启用它们”等方面,讨论还远未结束。
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 元素流入。
这是我以后想尝试的,但还没有尝试过。
<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 风险。