简体   繁体   English

html 以包含另一个 html

[英]html to include another html

I like the way Angular manage components.我喜欢 Angular 管理组件的方式。 I mean separate html, scss and js files.我的意思是单独的 html、scss 和 js 文件。 But I don't want to use Angular, Webpack or jQuery.但我不想使用 Angular、Webpack 或 jQuery。 I'm hoping to write a simple web app depending only on the native browser apis.我希望仅依赖本机浏览器 api 编写一个简单的 Web 应用程序。 I'm almost there, but the only thing that is blocking me is to include html templates into the index.html.我快到了,但唯一阻碍我的是将 html 模板包含到 index.html 中。 One way probably I could do would be to write a script to append all templates to the end of the index.html.我可能可以做的一种方法是编写一个脚本,将所有模板附加到 index.html 的末尾。 I tested it and it worked well.我对其进行了测试,效果很好。 But I wonder if there's any easier way that I am not aware of.但我想知道是否有任何我不知道的更简单的方法。 Please note I need zero dependency.请注意我需要零依赖。

index.html索引.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WSLD</title>
    <script type="module" src="my-summary.js"></script>
    <script type="module" src="my-detail.js"></script>
</head>
<body>
<my-summary></my-summary>
</body>
</html>

<template id="my-summary">
    <my-detail></my-detail>
    <my-detail></my-detail>
</template>

<template id="my-detail">
    <div>hello there</div>
</template>

my-summary.js我的摘要.js

customElements.define('my-summary',
    class extends HTMLElement {
        constructor() {
            super();
            const template = document.querySelector('#my-summary').content;
            this.attachShadow({mode: 'open'}).appendChild(template.cloneNode(true));
            // this.appendChild(template.cloneNode(true));

            const details = this.shadowRoot.querySelectorAll('my-detail');
            console.log(details);
            details[0].setAttribute('a', '123');
        }
    }
);

my-detail.js我的详细信息.js

customElements.define('my-detail',
    class extends HTMLElement {
        constructor() {
            super();
            const template = document.querySelector('#my-detail').content;
            const shadowRoot = this.attachShadow({mode: 'open'}).appendChild(template.cloneNode(true));
            // this.appendChild(template.cloneNode(true));
        }

        static get observedAttributes() {
            return ["a"];
        }

        attributeChangedCallback(name, oldValue, newValue) {
            console.log(name, oldValue, newValue);
        }
    }
);

Server Side Includes (SSI) let you include HTML files into HTML files.服务器端包含 (SSI)允许您将 HTML 文件包含到 HTML 文件中。 It is a mature feature of most web servers.它是大多数 Web 服务器的成熟功能。 Enable it and put an include statement into your HTML code:启用它并将包含语句放入您的 HTML 代码中:

<!--#include file="my-summary.html" -->
<!--#include file="my-detail.html" -->

Sometimes SSI is just enabled for files with the extension ".shtml".有时 SSI 只是为扩展名为“.shtml”的文件启用。

This is the fastest solution, because it does not require additional requests.这是最快的解决方案,因为它不需要额外的请求。 All HTML code gets delivered with the first request.所有 HTML 代码都随第一个请求一起交付。

Normally when I write WebComponents I create the template tag inside my js file.通常,当我编写 WebComponents 时,我会在我的 js 文件中创建模板标记。

for example:例如:

const template = document.createElement('template');
template.innerHTML = `<div>hello there</div>`;

So I have more control of my template.所以我可以更好地控制我的模板。

I attach a link with a well written guide for mastering WebComponents: https://dev.to/thepassle/web-components-from-zero-to-hero-4n4m我附上一个链接,其中包含一个精心编写的 WebComponents 指南: https ://dev.to/thepassle/web-components-from-zero-to-hero-4n4m

I would use the fetch API to grab the content of your template from the server and put the contents inside a DOM node.我将使用fetch API 从服务器获取模板的内容并将内容放入 DOM 节点中。 Something like this:像这样的东西:

my-detail.js我的详细信息.js

(() => {
  let templateContent = null;
  let onLoaded = [];
  (() => {
    let templateContainer = document.createElement("div");
    fetch("./my-detail.html")
      .then(res => res.text())
      .then(text => {
        templateContainer.innerHTML = text;
        templateContent = templateContainer.firstChild.content;
        onLoaded.forEach(cb => cb());
        loaded = true;
    });
  })();
  customElements.define(
    "my-detail",
    class extends HTMLElement {
      loaded = false;
      constructor() {
        super();
        const onLoad = () => {
          this.attachShadow({ mode: "open" }).appendChild(
            templateContent.cloneNode(true)
          );
        };
        if (templateContent != null) {
          onLoad();
        } else {
          onLoaded.push(onLoad);
        }
      }

      static get observedAttributes() {
        return ["a"];
      }

      attributeChangedCallback(name, oldValue, newValue) {
        console.log(name, oldValue, newValue);
      }
    }
  );
})();

my-detail.html我的详细信息.html

<template id="my-detail">
    <div>hello there</div>
</template>

You can obviously create some small utility function to simplify this logic so don't end up with a ton of duplicate code across your application.显然,您可以创建一些小的实用程序函数来简化此逻辑,这样就不会在您的应用程序中产生大量重复的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM