阴影内的脚本不起作用 [英] Script inside shadow dom not working

查看:132
本文介绍了阴影内的脚本不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建并导出了一个Angular Element(Angular中的Web组件)作为单个脚本标记(user-poll.js)。
要使用此Angular元素,我只需在主机站点中指定以下两行:

I've created and exported one Angular Element (web component in Angular) as a single script tag (user-poll.js). To use this Angular Element I just need to specify below two lines in the host site:

 <user-poll></user-poll>
 <script src="path/to/user-poll.js"></script>

工作JSBin示例

我有以下要求:


  1. 在外部网站上加载多个Angular元素。

  2. 动态加载所有Angular元素

我遇到以下问题:


  1. 在网站上加载多个组件会产生角度冲突,因为每个组件脚本都是一个完整的Angular应用程序。

  2. 为了解决冲突问题,我将每个组件加载到一个单独的 Shadow Dom 组件中(即添加组件标记和组件脚本文件)在阴影dom容器内链接),以便每个组件都是沙箱。但影子dom中的组件脚本无效。

  1. Loading multiple components on a site gives Angular conflicts, as each component script is a complete Angular app in itself.
  2. To solve conflict issue, I am loading each component in a separate Shadow Dom component (i.e. adding component tag and component script file link inside shadow dom container) so that each component is sandboxed. But component script inside shadow dom not working.

JSBin示例

<body>

</body>
    setTimeout(() => {
    loadJS();
}, 2000);
function loadJS() {
    var elm = document.createElement("div");
    elm.attachShadow({mode: "open"});
    elm.shadowRoot.innerHTML = `<user-poll><h2>Custom Web Component - user-poll loaded</h2><script src="https://cdn.rawgit.com/SaurabhLpRocks/795f67f8dc9652e5f119bd6060b58265/raw/d5490627b623f09c84cfecbd3d2bb8e09c743ed4/user-poll.js"><\/\script></user-poll>`;
    document.body.appendChild(elm);
}

那么,在网站上动态加载多个Angular元素的最佳方法是什么?

So, what is the best way to dynamically load multiple Angular Elements on a site?

推荐答案

脚本未执行的事实与Shadow DOM无关,而是与您尝试插入的方式无关< script> 元素,即通过 innerHTML 中的字符串。
在这种情况下,不解释字符串并且不执行脚本。

The fact that the script is not executed is not related to Shadow DOM, but to the way you try to insert the <script> element, that is via a string in innerHTML. In this case the string is not interpreted and the script not executed.

如果你想让它工作,你必须插入< ; script> via appendChild()

If you want it to work you must insert the <script> via appendChild().

您可以直接添加使用 createElement()创建的< script> 元素,或使用<模板> 元素。

You can do it directly by adding a <script> element created with createElement(), or by using a <template> element.

1。 with createElement()

创建< script> 元素并将其附加到其父元素:

Create a <script> element and append it to its parent:

var up = document.createElement( 'user-poll' )
var script = document.createElement( 'script' )
script.textContent = 'document.write( "executed" )'
up.appendChild( script )
elm.attachShadow( { mode: 'open' } )
   .appendChild( up )

<div id="elm"></div>

2。使用< template> 标记

2. with a <template> tag

附加的内容< template> 元素:

elm.attachShadow( { mode: 'open' } )
   .appendChild( tpl.content )

<template id="tpl">
    <user-poll>
        <script>document.write( 'exected' )</script>
    </user-poll>
</template>

<div id="elm"></div>

解析< template> 元素时,不执行该脚本,但是当它的内容附加到DOM。

The script is not executed when the <template> element is parsed, but when its content is appended to the DOM.

PS :无论如何我不确定这是最好的方法加载多个Angular元素:Shadow DOM不会充当Javascript代码的沙箱,因为< iframe> 可以。相反,也许你必须使用模块加载器。

PS: anyway I'm not sure it's the best way to load multiple Angular elements: Shadow DOM won't act as a sandbox for Javascript code, as <iframe> does. Instead maybe you'll have to use a module loader.

这篇关于阴影内的脚本不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆