13

由于 Html-Imports 现在在 Chrome 中已弃用(https://www.chromestatus.com/feature/5144752345317376)并将被删除,我想知道替代方案是什么。

我目前正在使用 Html-Imports 导入 Html-Templates。到目前为止,我只看到两种选择:

  • 将所有 HTML 文件捆绑在一个文件中。这也将改善生产中的下载时间,但这会减少封装和模块化。有一个聚合物捆绑器可以通过遍历分离的 HTML 文件中的 HTML-Import-Statements 来完成这项工作。但这意味着,即使将来任何浏览器都不支持 HTML 导入,它们也会保留在我的代码中。
  • 使用 XHttpRequests 构建某种模块加载器,并在运行时将模板编入一个 HTML 文件。这将保留封装和模块化,但这对我来说很糟糕,因为我基本上会自己重建导入语句。

有没有一种新的方式来导入 Html 模板?(通过“香草”我基本上是指一种不涉及任何额外工具(如预编译器或捆绑器)的方式)

4

2 回答 2

13

HTML Imports 的弃用从本质上改变了资源的加载顺序。自定义元素本质上已经成为脚本优先而不是模板优先。如果您的元素需要模板,请从脚本中加载它。如果没有,那就去上班吧。坦率地说,虽然我在最初的几周内对它有抵抗力,但我已经爱上了它。事实证明,加载模板等外部资源并没有那么糟糕。

下面是一些从外部文件加载 HTML 模板的简单代码:

使用异步/等待:

    async function getTemplate(filepath) {
        let response = await fetch(filepath);
        let txt = response.text();

        let html =  new DOMParser().parseFromString(txt, 'text/html');
        return html.querySelector('head > template');
    }

基于承诺:

    function getTemplate(filepath) {
        return fetch(filepath)
            .then(response => {
                let txt = response.text();
                let html = new DOMParser().parseFromString(txt, 'text/html');

                return html.querySelector('template');
            });
    }   

两者都可以通过以下两种方式调用:

异步/等待:

    let tpl = await getTemplate('path/to/template.html');

承诺:

    getTemplate('path/to/template.html')
        .then(function doSomething(tpl) {
            // Put your code here...
        });

生成的代码非常简单,可以通过多种方式轻松实现。事实上,我有一个小的 SuperClass 为我处理它,我所有的自定义元素都继承自它。相反,您可以使用 mixin,我过去也这样做过。

艰苦的工作只是颠倒订单,即使这样也不是很难,除非您使用 1000 多个组件。它可能只需很少的工作就可以实现自动化。

于 2019-02-01T00:35:58.690 回答
1

索引.html:

<script type="module">
  import { CustomHTMLElement } from './CustomHTMLElement.js'

  customElements.define('custom-html-element', CustomHTMLElement)
</script>

<custom-html-element></custom-html-element>

CustomHTMLElement.js:

import { createTemplate } from './createTemplate.js'

const template = createTemplate(`
  <template>
    <style>
      .box {
        width: 2rem;
        height: 2rem;
        background-color: red;
      }  
    </style>
    <div class="box"></div>
  </template>
`)

export class CustomHTMLElement extends HTMLElement {
  constructor() {
    super()
    const templateContent = template.content
    const shadowRoot = this.attachShadow({mode: 'closed'})
    shadowRoot.appendChild(templateContent.cloneNode(true))
  }
}

创建模板.js:

import { createDOM } from './createDOM.js'

export function createTemplate(templateText) {
  const dom = createDOM(templateText)
  const template = dom.querySelector('template')
  return template
}

创建DOM.js:

export function createDOM(htmlText) {
  return new DOMParser().parseFromString(htmlText, 'text/html')
}

请参阅https://github.com/SanjoSolutions/web-components以获取根据 Unlicense 许可许可的代码。

于 2021-01-30T14:04:33.810 回答