【问题标题】:Dynamically loading WebComponents Polyfill before page ready在页面准备好之前动态加载 WebComponents Polyfill
【发布时间】:2019-01-24 19:46:21
【问题描述】:

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

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

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

这是我正在尝试做的一个示例。

//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 的所有细节。

【问题讨论】:

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


    【解决方案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' )
                }
            } ) 
        )
    

    【讨论】:

    • 这很有帮助。但是,如果我在加载文档后定义自定义元素,浏览器是否知道返回这些元素并将它们重新呈现为适当的自定义元素?
    • @Andrew 是的,它会的。
    猜你喜欢
    • 1970-01-01
    • 2016-11-13
    • 2011-05-06
    • 1970-01-01
    • 2015-03-08
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多