在页面准备好之前动态加载 WebComponents Polyfill
Dynamically loading WebComponents Polyfill before page ready
我正在开发一个小部件库,这样客户只需在其文档的 <head>
中导入一个 javascript 文件。加载该文件后,用户应该能够使用从头部加载的单个脚本加载的自定义元素。
问题是我需要使用 WebComponents polyfill,因为并非所有客户端都使用支持自定义元素的浏览器。
我当前的 "solution"(不一致)是我有自己的捆绑包:
- 通过插入脚本来动态包含 WebComponents 包以在
<head>
中加载它。
- 我想使用 WebComponents-Loader,它会进行额外的调用以仅获取所需的 polyfill。
- 加载我的代码,其中包含自定义元素。
结果应该是客户可以在他们的页面上使用我们的任何自定义元素。问题是当我动态插入 web 组件 polyfill 时,浏览器似乎一直在继续,如果 DOM 在浏览器完成 loading/executing web 组件 polyfill 之前就准备好了,那么屏幕上的 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 的所有来龙去脉。
您可以在定义自定义元素之前等待 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' )
}
} )
)
我正在开发一个小部件库,这样客户只需在其文档的 <head>
中导入一个 javascript 文件。加载该文件后,用户应该能够使用从头部加载的单个脚本加载的自定义元素。
问题是我需要使用 WebComponents polyfill,因为并非所有客户端都使用支持自定义元素的浏览器。
我当前的 "solution"(不一致)是我有自己的捆绑包:
- 通过插入脚本来动态包含 WebComponents 包以在
<head>
中加载它。- 我想使用 WebComponents-Loader,它会进行额外的调用以仅获取所需的 polyfill。
- 加载我的代码,其中包含自定义元素。
结果应该是客户可以在他们的页面上使用我们的任何自定义元素。问题是当我动态插入 web 组件 polyfill 时,浏览器似乎一直在继续,如果 DOM 在浏览器完成 loading/executing web 组件 polyfill 之前就准备好了,那么屏幕上的 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 的所有来龙去脉。
您可以在定义自定义元素之前等待 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' )
}
} )
)