在页面准备就绪之前动态加载WebComponents Polyfill

时间:2018-08-17 18:16:35

标签: javascript html polymer web-component custom-element

我正在使用小部件库,因此客户仅需在其文档的<head>中导入单个javascript文件。加载该文件后,用户应该能够使用从头部中加载的单个脚本加载的自定义元素。
问题在于我需要使用WebComponents polyfill,因为不是所有的客户端都使用支持自定义元素的浏览器。
我当前的“解决方案”(不一致)是我有自己的捆绑软件:

  1. 通过插入脚本以将其加载到<head>中来动态地包含WebComponents捆绑包。
    • 我想使用WebComponents-Loader进行附加调用,以仅获取所需的polyfill。
  2. 加载包含自定义元素的代码。

结果应该是客户可以在其页面上使用我们的任何自定义元素。问题是,当我动态插入Web组件polyfill时,似乎浏览器一直在运行,如果在浏览器完成加载/执行Web组件polyfill之前DOM已准备就绪,则屏幕上的Web组件会赢不行

这是我要做的事的一个例子。

//bundle-test.js
let polyfillScript = document.createElement('script');
polyfillScript.src = 'widget/webcomponentsjs/webcomponents-bundle.js';
polyfillScript.async = false;
document.head.appendChild(polyfillScript);

...
<html>
    <head>
        <script src="widget/bundle-test.js"></script>
        <!--The above script will dynamically insert the script commented below-->
        <!--<script src="widget/webcomponentsjs/webcomponents-bundle.js" async="false"></script>-->
    </head>
    <body>
        <h1>Hello world!</h1>
        <document-viewer test='food'></document-viewer>
    </body>
</html>

我已经告诉脚本不要异步(应该已经解决了)。但是我看到浏览器只是继续运行到身体上,并在一切准备就绪之前开始评估事物。

我想做的事有更好的方法吗?我仍在尝试弄清WebComponents的所有来龙去脉。

1 个答案:

答案 0 :(得分:1)

在定义自定义元素之前,您可以等待polyfill加载:

//bundle-test.js
let polyfillScript = document.createElement('script');
polyfillScript.src = '/webcomponentsjs/webcomponents-bundle.js';
polyfillScript.async = false;
document.head.appendChild(polyfillScript);

polyfillScript.onload = () =>
  customElements.define( 'document-viewer', class extends HTMLElement {
    connectedCallback() {
      this.innerHTML = this.getAttribute( 'test' )
    }
  } )

或者,如果您想改用 webcomponents-loader.js ,则还必须使用WebComponents.waitFor

...
polyfillScript.onload = () =>
    WebComponents.waitFor( () =>
        customElements.define( 'document-viewer', class extends HTMLElement {
            connectedCallback() {
                this.innerHTML = this.getAttribute( 'test' )
            }
        } ) 
    )