【问题标题】:Include another HTML file in a HTML file在 HTML 文件中包含另一个 HTML 文件
【发布时间】:2012-02-17 19:39:28
【问题描述】:

我有 2 个 HTML 文件,假设 a.htmlb.html。在a.html 中我想包含b.html

在 JSF 中我可以这样做:

<ui:include src="b.xhtml" />

这意味着在a.xhtml文件中,我可以包含b.xhtml

我们如何在*.html文件中做到这一点?

【问题讨论】:

标签: javascript html dom include


【解决方案1】:

扩展lolo's answer,如果您必须包含大量文件,这里会更加自动化。使用这个 JS 代码:

$(function () {
  var includes = $('[data-include]')
  $.each(includes, function () {
    var file = 'views/' + $(this).data('include') + '.html'
    $(this).load(file)
  })
})

然后在 html 中包含一些内容:

<div data-include="header"></div>
<div data-include="footer"></div>

这将包括文件views/header.htmlviews/footer.html

【讨论】:

  • 非常有用。有没有办法通过另一个数据参数传递一个参数,比如data-argument 并在包含的文件中检索它?
  • @chris 您可以使用 GET 参数,例如$("#postdiv").load('posts.php?name=Test&amp;age=25');
  • 无法在带有本地文件的 chrome 上工作“跨源请求仅支持协议方案:htt”
  • @ArtemBernatskyi 当您运行本地服务器时有帮助吗?这是一个简单的教程:developer.mozilla.org/en-US/docs/Learn/Common_questions/…
【解决方案2】:

w3.js 很酷。

https://www.w3schools.com/lib/w3.js

我们是重点

w3-include-html

但请考虑以下情况

- ? popup.html
- ? popup.js
- ? include.js
- ? partials 
   - ? head
         - ? bootstrap-css.html
         - ? fontawesome-css.html
         - ? all-css.html
   - ? hello-world.html
<!-- popup.html -->
<head>
<script defer type="module" src="popup.js"></script>
<meta data-include-html="partials/head/all-css.html">
</head>

<body>
<div data-include-html="partials/hello-world.html"></div>
</body>
<!-- bootstrap-css.html -->
<link href="https://.../bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" />

<!-- fontawesome-css.html -->
<link rel="stylesheet" href="https://.../font-awesome/5.15.4/css/all.min.css" />
<!-- all-css.html -->
<meta data-include-html="bootstrap-css.html">
<meta data-include-html="fontawesome-css.html">

<!-- 
If you want to use w3.js.include, you should change as below

<meta w3-include-html="partials/head/bootstrap-css.html">
<meta w3-include-html="partials/head/fontawesome-css.html">

Of course, you can add the above in the ``popup.html`` directly.

If you don't want to, then consider using my scripts.
-->
<!-- hello-world.html -->
<h2>Hello World</h2>

脚本

// include.js

const INCLUDE_TAG_NAME = `data-include-html`

/**
 * @param {Element} node
 * @param {Function} cb callback
 * */
export async function includeHTML(node, {
  cb = undefined
}) {
  const nodeArray = node === undefined ?
    document.querySelectorAll(`[${INCLUDE_TAG_NAME}]`) :
    node.querySelectorAll(`[${INCLUDE_TAG_NAME}]`)

  if (nodeArray === null) {
    return
  }

  for (const node of nodeArray) {
    const filePath = node.getAttribute(`${INCLUDE_TAG_NAME}`)
    if (filePath === undefined) {
      return
    }

    await new Promise(resolve => {
      fetch(filePath
      ).then(async response => {
          const text = await response.text()
          if (!response.ok) {
            throw Error(`${response.statusText} (${response.status}) | ${text} `)
          }
          node.innerHTML = text
          const rootPath = filePath.split("/").slice(0, -1)
          node.querySelectorAll(`[${INCLUDE_TAG_NAME}]`).forEach(elem=>{
            const relativePath = elem.getAttribute(`${INCLUDE_TAG_NAME}`) // not support ".."
            if(relativePath.startsWith('/')) { // begin with site root.
              return
            }
            elem.setAttribute(`${INCLUDE_TAG_NAME}`, [...rootPath, relativePath].join("/"))
          })
          node.removeAttribute(`${INCLUDE_TAG_NAME}`)
          await includeHTML(node, {cb})
          node.replaceWith(...node.childNodes) // https://stackoverflow.com/a/45657273/9935654
          resolve()
        }
      ).catch(err => {
        node.innerHTML = `${err.message}`
        resolve()
      })
    })
  }

  if (cb) {
    cb()
  }
}
// popup.js

import * as include from "include.js"

window.onload = async () => {
  await include.includeHTML(undefined, {})
  // ...
}

输出

<!-- popup.html -->

<head>

<link href="https://.../bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://.../font-awesome/5.15.4/css/all.min.css" />
</head>

<body>
<h2>Hello World</h2>
</body>

【讨论】:

    【解决方案3】:

    这里有几种类型的答案,但我从来没有找到这里使用的最古老的工具:

    “而所有其他答案对我都不起作用。”

    <html>
    <head>   
        <title>pagetitle</title>
    </head>
    
    <frameset rows="*" framespacing="0" border="0" frameborder="no" frameborder="0">
        <frame name="includeName" src="yourfileinclude.html" marginwidth="0" marginheight="0" scrolling="no" frameborder="0">   
    </frameset>
    
    </html>
    

    【讨论】:

      【解决方案4】:

      仅使用 HTML 是不可能在另一个 HTML 文件中包含 HTML 文件的。但这里有一个非常简单的方法来做到这一点。 Using this JS library 你可以轻松做到这一点。只需使用此代码:

      <script> include('path/to/file.html', document.currentScript) </script>
      

      【讨论】:

      • 链接给出 404
      【解决方案5】:

      一个简单的服务器端包含指令包含在同一文件夹中找到的另一个文件,如下所示:

      <!--#include virtual="a.html" --> 
      

      你也可以试试:

      <!--#include file="a.html" -->
      

      【讨论】:

      • 您需要配置您的服务器以使用 SSI
      • 这里是为您的服务器配置 SSI 的参考:httpd.apache.org/docs/2.4/howto/ssi.html#configuring
      • 可能也值得一试&lt;!--#include file="a.html" --&gt;
      • SSI 包含使 Web 服务器变慢了一点(因此在绝对必要之前应避免使用)。
      • 对于 IIS,这也是一个不错的解决方案。我必须将` ` 添加到我的web.config 文件中在&lt;handlers&gt; 部分
      【解决方案6】:

      这是我的内联解决方案:

      (() => {
          const includes = document.getElementsByTagName('include');
          [].forEach.call(includes, i => {
              let filePath = i.getAttribute('src');
              fetch(filePath).then(file => {
                  file.text().then(content => {
                      i.insertAdjacentHTML('afterend', content);
                      i.remove();
                  });
              });
          });
      })();
      <p>FOO</p>
      
      <include src="a.html">Loading...</include>
      
      <p>BAR</p>
      
      <include src="b.html">Loading...</include>
      
      <p>TEE</p>

      【讨论】:

      • 它可以工作,但脚本不适用于此包含的文档。
      • @MuhammadSaquibShaikh 你的意思是sn-p吗?它肯定行不通,因为 jsfiddle 没有多文件基础架构
      • 我正在加载另一个 html 文件(具有 js 文件的脚本标签),但 js 代码显示 null 以选择 DOM 元素
      【解决方案7】:

      使用includeHTML(最小的 js-lib:~150 行)

      通过 HTML 标签加载 HTML 部分(纯 js)
      支持的负载:异步/同步,任何深度递归包括

      支持的协议:http://、https://、file:///
      支持的浏览器:IE 9+、FF、Chrome(可能还有其他)

      用法:

      1.将 includeHTML 插入 HTML 文件的头部(或正文关闭标记之前):

      <script src="js/includeHTML.js"></script>
      

      2.Anywhere 使用 includeHTML 作为 HTML 标签:

      <div data-src="header.html"></div>
      

      【讨论】:

      • @Williams,非常感谢您反馈我的工作!
      【解决方案8】:

      我来到这个主题是为了寻找类似的东西,但与 lolo 提出的问题有点不同。我想构建一个 HTML 页面,其中包含一个按字母顺序排列的指向其他页面的链接菜单,其他每个页面可能存在也可能不存在,并且它们的创建顺序可能不是字母顺序(甚至不是数字)。另外,像 Tafkadasoh 一样,我不想用 jQuery 使网页膨胀。在研究了这个问题并试验了几个小时后,这对我有用,并添加了相关的注释:

      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      <html>
      <head>
        <meta http-equiv="Content-Type" content="text/application/html; charset=iso-8859-1">
        <meta name="Author" content="me">
        <meta copyright="Copyright" content= "(C) 2013-present by me" />
        <title>Menu</title>
      
      <script type="text/javascript">
      <!--
      var F000, F001, F002, F003, F004, F005, F006, F007, F008, F009,
          F010, F011, F012, F013, F014, F015, F016, F017, F018, F019;
      var dat = new Array();
      var form, script, write, str, tmp, dtno, indx, unde;
      
      /*
      The "F000" and similar variables need to exist/be-declared.
      Each one will be associated with a different menu item,
      so decide on how many items maximum you are likely to need,
      when constructing that listing of them.  Here, there are 20.
      */
      
      
      function initialize()
      { window.name="Menu";
        form = document.getElementById('MENU');
        for(indx=0; indx<20; indx++)
        { str = "00" + indx;
          tmp = str.length - 3;
          str = str.substr(tmp);
          script = document.createElement('script');
          script.type = 'text/javascript';
          script.src = str + ".js";
          form.appendChild(script);
        }
      
      /*
      The for() loop constructs some <script> objects
      and associates each one with a different simple file name,
      starting with "000.js" and, here, going up to "019.js".
      It won't matter which of those files exist or not.
      However, for each menu item you want to display on this
      page, you will need to ensure that its .js file does exist.
      
      The short function below (inside HTML comment-block) is,
      generically, what the content of each one of the .js files looks like:
      <!--
      function F000()
      { return ["Menu Item Name", "./URLofFile.htm", "Description string"];
      }
      -->
      
      (Continuing the remarks in the main menu.htm file)
      It happens that each call of the form.appendChild() function
      will cause the specified .js script-file to be loaded at that time.
      However, it takes a bit of time for the JavaScript in the file
      to be fully integrated into the web page, so one thing that I tried,
      but it didn't work, was to write an "onload" event handler.
      The handler was apparently being called before the just-loaded
      JavaScript had actually become accessible.
      
      Note that the name of the function in the .js file is the same as one
      of the pre-defined variables like "F000".  When I tried to access
      that function without declaring the variable, attempting to use an
      "onload" event handler, the JavaScript debugger claimed that the item
      was "not available".  This is not something that can be tested-for!
      However, "undefined" IS something that CAN be tested-for.  Simply
      declaring them to exist automatically makes all of them "undefined".
      When the system finishes integrating a just-loaded .js script file,
      the appropriate variable, like "F000", will become something other
      than "undefined".  Thus it doesn't matter which .js files exist or
      not, because we can simply test all the "F000"-type variables, and
      ignore the ones that are "undefined".  More on that later.
      
      The line below specifies a delay of 2 seconds, before any attempt
      is made to access the scripts that were loaded.  That DOES give the
      system enough time to fully integrate them into the web page.
      (If you have a really long list of menu items, or expect the page
      to be loaded by an old/slow computer, a longer delay may be needed.)
      */
      
        window.setTimeout("BuildMenu();", 2000);
        return;
      }
      
      
      //So here is the function that gets called after the 2-second delay  
      function BuildMenu()
      { dtno = 0;    //index-counter for the "dat" array
        for(indx=0; indx<20; indx++)
        { str = "00" + indx;
          tmp = str.length - 3;
          str = "F" + str.substr(tmp);
          tmp = eval(str);
          if(tmp != unde) // "unde" is deliberately undefined, for this test
            dat[dtno++] = eval(str + "()");
        }
      
      /*
      The loop above simply tests each one of the "F000"-type variables, to
      see if it is "undefined" or not.  Any actually-defined variable holds
      a short function (from the ".js" script-file as previously indicated).
      We call the function to get some data for one menu item, and put that
      data into an array named "dat".
      
      Below, the array is sorted alphabetically (the default), and the
      "dtno" variable lets us know exactly how many menu items we will
      be working with.  The loop that follows creates some "<span>" tags,
      and the the "innerHTML" property of each one is set to become an
      "anchor" or "<a>" tag, for a link to some other web page.  A description
      and a "<br />" tag gets included for each link.  Finally, each new
      <span> object is appended to the menu-page's "form" object, and thereby
      ends up being inserted into the middle of the overall text on the page.
      (For finer control of where you want to put text in a page, consider
      placing something like this in the web page at an appropriate place,
      as preparation:
      <div id="InsertHere"></div>
      You could then use document.getElementById("InsertHere") to get it into
      a variable, for appending of <span> elements, the way a variable named
      "form" was used in this example menu page.
      
      Note: You don't have to specify the link in the same way I did
      (the type of link specified here only works if JavaScript is enabled).
      You are free to use the more-standard "<a>" tag with the "href"
      property defined, if you wish.  But whichever way you go,
      you need to make sure that any pages being linked actually exist!
      */
      
        dat.sort();
        for(indx=0; indx<dtno; indx++)
        { write = document.createElement('span');
          write.innerHTML = "<a onclick=\"window.open('" + dat[indx][1] +
                            "', 'Menu');\" style=\"color:#0000ff;" + 
                            "text-decoration:underline;cursor:pointer;\">" +
                            dat[indx][0] + "</a> " + dat[indx][2] + "<br />";
          form.appendChild(write);
        }
        return;
      }
      
      // -->
      </script>
      </head>
      
      <body onload="initialize();" style="background-color:#a0a0a0; color:#000000; 
      
      font-family:sans-serif; font-size:11pt;">
      <h2>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MENU
      <noscript><br /><span style="color:#ff0000;">
      Links here only work if<br />
      your browser's JavaScript<br />
      support is enabled.</span><br /></noscript></h2>
      These are the menu items you currently have available:<br />
      <br />
      <form id="MENU" action="" onsubmit="return false;">
      <!-- Yes, the <form> object starts out completely empty -->
      </form>
      Click any link, and enjoy it as much as you like.<br />
      Then use your browser's BACK button to return to this Menu,<br />
      so you can click a different link for a different thing.<br />
      <br />
      <br />
      <small>This file (web page) Copyright (c) 2013-present by me</small>
      </body>
      </html>
      

      【讨论】:

        【解决方案9】:

        网页组件

        我创建了类似于 JSF 的 web-component

        <ui-include src="b.xhtml"><ui-include>
        

        can use它作为你页面中的常规html标签(包括sn-p js代码之后)

        customElements.define('ui-include', class extends HTMLElement {
          async connectedCallback() {
            let src = this.getAttribute('src');
            this.innerHTML = await (await fetch(src)).text();;
          }
        })
        ui-include { margin: 20px } /* example CSS */
        <ui-include src="https://cors-anywhere.herokuapp.com/https://example.com/index.html"></ui-include>
        
        <div>My page data... - in this snippet styles overlaps...</div>
        
        <ui-include src="https://cors-anywhere.herokuapp.com/https://www.w3.org/index.html"></ui-include>

        【讨论】:

        • 我们如何在没有 JavaScript 的情况下做到这一点
        • 在该元素上使用display: contents 可能也有意义,以使 布局消失。我认为这是预期的行为。
        【解决方案10】:

        无论你的项目是否是 AngularJS,我都强烈建议使用 AngularJS 的ng-include

        <script src=".../angular.min.js"></script>
        
        <body ng-app="ngApp" ng-controller="ngCtrl">
        
            <div ng-include="'another.html'"></div> 
        
            <script>
                var app = angular.module('ngApp', []);
                app.controller('ngCtrl', function() {});
            </script>
        
        </body>
        

        您可以从AngularJS 找到 CDN(或下载 Zip),从W3Schools 找到更多信息。

        【讨论】:

        • 如果您使用 JavaScript,则不必为此使用 angular。没有任何 JavaScript 怎么办呢
        • @bluejayke 是不是很简单?不到 10 行代码,没有任何自定义定义。
        【解决方案11】:

        我还有另一种解决方案来做到这一点

        在 JavaScript 中使用 Ajax

        这里是 Github repo 中的解释代码 https://github.com/dupinder/staticHTML-Include

        基本思路是:

        index.html

        <!DOCTYPE html>
        <html>
        <head>
            <meta charset='utf-8'>
            <meta http-equiv='X-UA-Compatible' content='IE=edge'>
            <title>Page Title</title>
            <meta name='viewport' content='width=device-width, initial-scale=1'>
            <script src='main.js'></script>
        
        
        </head>
        <body>
            <header></header>
        
            <footer></footer>
        </body>
        </html>
        

        main.js

        fetch("./header.html")
          .then(response => {
            return response.text()
          })
          .then(data => {
            document.querySelector("header").innerHTML = data;
          });
        
        fetch("./footer.html")
          .then(response => {
            return response.text()
          })
          .then(data => {
            document.querySelector("footer").innerHTML = data;
          });
        

        【讨论】:

        • 这不会在导入文件中运行附加的 js 函数。你有什么解决办法吗?
        • 如果您尝试运行在footer.htmlheader.html 中链接的some.js 文件,那么您以错误的方式感知这一点。此解决方案仅适用于网页中的 HTML 组件插件。您需要创建一个 JS 插件,它将导入您所需的所有 JS 文件
        • 不支持 URL 方案“文件”。
        【解决方案12】:

        我的解决方案类似于上面的lolo 之一。但是,我通过 JavaScript 的 document.write 插入 HTML 代码,而不是使用 jQuery:

        a.html:

        <html> 
          <body>
          <h1>Put your HTML content before insertion of b.js.</h1>
              ...
        
          <script src="b.js"></script>
        
              ...
        
          <p>And whatever content you want afterwards.</p>
          </body>
        </html>
        

        b.js:

        document.write('\
        \
            <h1>Add your HTML code here</h1>\
        \
             <p>Notice however, that you have to escape LF's with a '\', just like\
                demonstrated in this code listing.\
            </p>\
        \
        ');
        

        我反对使用 jQuery 的原因是 jQuery.js 的大小约为 90kb,我希望加载的数据量尽可能小。

        为了不费吹灰之力得到正确转义的 JavaScript 文件,可以使用以下 sed 命令:

        sed 's/\\/\\\\/g;s/^.*$/&\\/g;s/'\''/\\'\''/g' b.html > escapedB.html
        

        或者只是使用以下作为 Gist 在 Github 上发布的便捷 bash 脚本,它可以自动完成所有必要的工作,将 b.html 转换为 b.jshttps://gist.github.com/Tafkadasoh/334881e18cbb7fc2a5c033bfa03f6ee6

        感谢Greg Minshall 改进的 sed 命令,该命令还转义了反斜杠和单引号,我原来的 sed 命令没有考虑这些。

        对于支持template literals 的浏览器,也可以使用以下方法:

        b.js:

        document.write(`
        
            <h1>Add your HTML code here</h1>
        
             <p>Notice, you do not have to escape LF's with a '\',
                like demonstrated in the above code listing.
            </p>
        
        `);
        

        【讨论】:

        • @TrevorHickey 是的,你是对的,这是我的解决方案的缺点,而且不是很优雅。但是,由于您可以在每行的末尾插入一个带有简单正则表达式的 '\',这对我来说效果最好。嗯...也许我应该在我的答案中添加如何通过正则表达式进行插入...
        • 天哪,这太丑了——不用了,谢谢。我宁愿把我的 html 写成 html。我不在乎是否可以在命令行上使用 sed - 我不想每次更改模板的内容时都依赖它。
        • @Goodra 它应该适用于任何没有' 标记的HTML。如果您只是执行查找/替换以替换 ` with \` 那么查找/替换以将 ' 替换为 \' 并将新行替换为 ``new-lines 它会正常工作。
        • @wizzwizz4:感谢 Greg,sed 命令现在还可以转义单引号和反斜杠。此外,我添加了一个 bash 脚本,它可以为您完成所有工作。 :-)
        • 你可以使用反引号` - 然后你可以插入像${var} 这样的表达式 - 你只需要转义\`\$
        【解决方案13】:

        您是否尝试过 iFrame 注入?

        它在文档中注入 iFrame 并删除自己(它应该在 HTML DOM 中)

        &lt;iframe src="header.html" onload="this.before((this.contentDocument.body||this.contentDocument).children[0]);this.remove()"&gt;&lt;/iframe&gt;

        问候

        【讨论】:

          【解决方案14】:

          要使解决方案正常工作,您需要包含文件 csi.min.js,您可以找到 here

          根据 GitHub 上显示的示例,要使用此库,您必须在页面标题中包含文件 csi.js,然后您需要将 data-include 属性及其值设置添加到要包含的文件中,在容器元素上。

          隐藏复制代码

          <html>
            <head>
              <script src="csi.js"></script>
            </head>
            <body>
              <div data-include="Test.html"></div>
            </body>
          </html>
          

          ...希望对您有所帮助。

          【讨论】:

            【解决方案15】:

            在 w3.js 中包含这样的作品:

            <body>
            <div w3-include-HTML="h1.html"></div>
            <div w3-include-HTML="content.html"></div>
            <script>w3.includeHTML();</script>
            </body>
            

            如需正确描述,请查看:https://www.w3schools.com/howto/howto_html_include.asp

            【讨论】:

            • 如果你想知道文档是什么时候被加载的,你可以把这个放在文档的最后: 聪明的把戏,嗯?
            【解决方案16】:

            另一种使用 Fetch API 和 Promise 的方法

            <html>
             <body>
              <div class="root" data-content="partial.html">
              <script>
                  const root = document.querySelector('.root')
                  const link = root.dataset.content;
            
                  fetch(link)
                    .then(function (response) {
                      return response.text();
                    })
                    .then(function (html) {
                      root.innerHTML = html;
                    });
              </script>
             </body>
            </html>
            

            【讨论】:

              【解决方案17】:

              这是我使用 Fetch API 和异步函数的方法

              <div class="js-component" data-name="header" data-ext="html"></div>
              <div class="js-component" data-name="footer" data-ext="html"></div>
              
              <script>
                  const components = document.querySelectorAll('.js-component')
              
                  const loadComponent = async c => {
                      const { name, ext } = c.dataset
                      const response = await fetch(`${name}.${ext}`)
                      const html = await response.text()
                      c.innerHTML = html
                  }
              
                  [...components].forEach(loadComponent)
              </script>
              

              【讨论】:

                【解决方案18】:

                使用 ES6 反引号 ``: template literals!

                let nick = "Castor", name = "Moon", nuts = 1
                
                more.innerHTML = `
                
                <h1>Hello ${nick} ${name}!</h1>
                
                You collected ${nuts} nuts so far!
                
                <hr>
                
                Double it and get ${nuts + nuts} nuts!!
                
                ` 
                &lt;div id="more"&gt;&lt;/div&gt;

                这样我们可以在不编码引号的情况下包含 html,包含来自 DOM 的变量等等。

                它是一个强大的模板引擎,我们可以使用单独的js文件并使用事件将内容加载到位,甚至可以将所有内容分块并按需调用:

                let inject = document.createElement('script');
                inject.src= '//....com/template/panel45.js';
                more.appendChild(inject);
                

                https://caniuse.com/#feat=template-literals

                【讨论】:

                • 嘿,你是对的,在 2018 年,以上是一个真正好的 RTFM 的明显标志;)直到那时,我作为一个业余程序员,很大程度上粉碎了 javascript 徽章。
                【解决方案19】:

                我知道这是一篇很老的帖子,所以当时还没有一些方法。 但这是我非常简单的看法(基于 Lolo 的回答)。

                它依赖于 HTML5 的 data-* 属性,因此非常通用,因为它使用 jQuery 的 for-each 函数来获取与“load-html”匹配的每个 .class,并使用其各自的 'data-source' 属性来加载内容:

                <div class="container-fluid">
                    <div class="load-html" id="NavigationMenu" data-source="header.html"></div>
                    <div class="load-html" id="MainBody" data-source="body.html"></div>
                    <div class="load-html" id="Footer" data-source="footer.html"></div>
                </div>
                <script src="js/jquery.min.js"></script>
                <script>
                $(function () {
                    $(".load-html").each(function () {
                        $(this).load(this.dataset.source);
                    });
                });
                </script>
                

                【讨论】:

                  【解决方案20】:

                  您可以使用 HTML Imports (https://www.html5rocks.com/en/tutorials/webcomponents/imports/) 的 polyfill,或者简化的解决方案 https://github.com/dsheiko/html-import

                  例如,在页面上,您可以像这样导入 HTML 块:

                  <link rel="html-import" href="./some-path/block.html" >
                  

                  块可能有自己的导入:

                  <link rel="html-import" href="./some-other-path/other-block.html" >
                  

                  导入器用加载的 HTML 替换指令,就像 SSI 一样

                  这些指令将在您加载这个小 JavaScript 时自动提供:

                  <script async src="./src/html-import.js"></script>
                  

                  当 DOM 准备好时,它会自动处理导入。此外,它还公开了一个 API,您可以使用该 API 手动运行、获取日志等。享受:)

                  【讨论】:

                  • 脚本行应该放在html文件的什么位置?
                  • 身体内的任何地方。可以递归放置在包含文件的内容中
                  • 你测试过这个吗?
                  • 我确实做到了。我实际上已经使用它多年了。为什么问?有什么问题吗?
                  • 所以“关键”似乎是script async src。试试看!
                  【解决方案21】:

                  这对我有帮助。要将一段html代码从b.html添加到a.html,这应该进入a.htmlhead标签:

                  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
                  

                  然后在body标签中,用一个唯一的id和一个javascript块制作一个容器,将b.html加载到容器中,如下:

                  <div id="b-placeholder">
                  
                  </div>
                  
                  <script>
                  $(function(){
                    $("#b-placeholder").load("b.html");
                  });
                  </script>
                  

                  【讨论】:

                  • 这个答案与这个问题的公认答案有何不同?
                  • @MohammadUsman 这里容器和javascript代码位于body标签中,而接受的答案将它们放在head标签中,而容器仅留在body标签中。
                  • 这不值得一个新的答案......这是一个评论
                  【解决方案22】:

                  html5rocks.com 有一个很好的关于这东西的教程,这可能有点晚了,但我自己并不知道它的存在。 w3schools 也有一种方法可以使用他们名为 w3.js 的新库来做到这一点。问题是,这需要使用 Web 服务器和 HTTPRequest 对象。您实际上无法在本地加载这些并在您的机器上测试它们。不过,您可以做的是使用顶部 html5rocks 链接上提供的 polyfill,或者按照他们的教程进行操作。用一点 JS 魔法,你可以做这样的事情:

                   var link = document.createElement('link');
                   if('import' in link){
                       //Run import code
                       link.setAttribute('rel','import');
                       link.setAttribute('href',importPath);
                       document.getElementsByTagName('head')[0].appendChild(link);
                       //Create a phantom element to append the import document text to
                       link = document.querySelector('link[rel="import"]');
                       var docText = document.createElement('div');
                       docText.innerHTML = link.import;
                       element.appendChild(docText.cloneNode(true));
                   } else {
                       //Imports aren't supported, so call polyfill
                       importPolyfill(importPath);
                   }
                  

                  这将创建链接(如果已经设置,可以更改为想要的链接元素),设置导入(除非你已经拥有它),然后附加它。然后它将从那里获取并解析 HTML 中的文件,然后将其附加到 div 下的所需元素。这一切都可以根据您的需要进行更改,从附加元素到您正在使用的链接。我希望这会有所帮助,如果在不使用 jQuery 或 W3.js 等库和框架的情况下出现了更新、更快的方法,那么现在可能无关紧要了。

                  更新:这将引发错误,指出本地导入已被 CORS 策略阻止。由于深度网络的属性,可能需要访问深度网络才能使用它。 (表示没有实际用途)

                  【讨论】:

                    【解决方案23】:

                    在我看来,最好的解决方案是使用 jQuery:

                    a.html:

                    <html> 
                      <head> 
                        <script src="jquery.js"></script> 
                        <script> 
                        $(function(){
                          $("#includedContent").load("b.html"); 
                        });
                        </script> 
                      </head> 
                    
                      <body> 
                         <div id="includedContent"></div>
                      </body> 
                    </html>
                    

                    b.html:

                    <p>This is my include file</p>
                    

                    这种方法是解决我的问题的简单而干净的方法。

                    jQuery .load() 文档是 here

                    【讨论】:

                    • 只做这个 ` 有什么区别?
                    • @RodrigoRuiz $(function(){}) 只会在文档加载完成后执行。
                    • 如果包含的 HTML 文件附加了 CSS,它可能会弄乱您的页面样式。
                    • 我和你提到的完全一样。我正在使用引导程序并为 B.html 覆盖 css。当我在 A.html 中使用 B.html 以使其最终成为 A.html 的标题时,我可以看到 css 已失去其优先级并且具有不同的布局。有什么解决办法吗?。
                    • 这确实需要服务器。在本地文件上使用它时:XMLHttpRequest cannot load file:///.../b.html. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
                    【解决方案24】:

                    结帐 HTML5 导入 via Html5rocks tutorial polymer-project

                    例如:

                    <head>
                      <link rel="import" href="/path/to/imports/stuff.html">
                    </head>
                    

                    【讨论】:

                    • HTML 导入并不意味着直接将内容包含在页面中。此答案中的代码仅使stuff.html 在父页面中作为模板 可用,但您必须使用脚本在父页面中创建其DOM 的克隆页面,以便用户可以看到它们。
                    • html5rocks.com 上关于将一个 HTML 页面的内容插入另一个 HTML 页面的说明似乎还不适用于许多浏览器。我在 Opera 12.16 和 Superbird 版本 32.0.1700.7 (233448) 中尝试过,但没有效果(在 Xubuntu 15.04 上)。不过,我听说它在 Firefox(由于希望已修复的错误)或许多版本的 Chrome 中不起作用。因此,虽然它看起来可能是未来的理想解决方案,但它并不是一个跨浏览器的解决方案。
                    • Firefox 将不支持它。要启用它,请尝试设置“dom.webcomponents.enabled”。它仅适用于 Chrome 和 Opera,具有可更新 Web 视图的 Android (startng 4.4.3)。苹果浏览器不支持。对于 Web 组件来说,这看起来是一个不错的想法,但尚未广泛实施。
                    • 2018 年末更新:HTML 导入显然是 deprecated for some reason
                    • HTML 导入已被弃用,并已于 2020 年 2 月从 Chrome 中删除。
                    【解决方案25】:

                    根据https://stackoverflow.com/a/31837264/4360308的回答 我已经用 Nodejs (+ express +cheerio) 实现了这个功能,如下所示:

                    HTML (index.html)

                    <div class="include" data-include="componentX" data-method="append"></div>
                    <div class="include" data-include="componentX" data-method="replace"></div>
                    

                    JS

                    function includeComponents($) {
                        $('.include').each(function () {
                            var file = 'view/html/component/' + $(this).data('include') + '.html';
                            var dataComp = fs.readFileSync(file);
                            var htmlComp = dataComp.toString();
                            if ($(this).data('method') == "replace") {
                                $(this).replaceWith(htmlComp);
                            } else if ($(this).data('method') == "append") {
                                $(this).append(htmlComp);
                            }
                        })
                    }
                    
                    function foo(){
                        fs.readFile('./view/html/index.html', function (err, data) {
                            if (err) throw err;
                            var html = data.toString();
                            var $ = cheerio.load(html);
                            includeComponents($);
                            ...
                        }
                    }
                    

                    追加 -> 将内容包含到 div 中

                    replace -> 替换 div

                    您可以按照相同的设计轻松添加更多行为

                    【讨论】:

                      【解决方案26】:

                      你可以像这样使用 JavaScript 的库 jQuery 来做到这一点:

                      HTML:

                      <div class="banner" title="banner.html"></div>
                      

                      JS:

                      $(".banner").each(function(){
                          var inc=$(this);
                          $.get(inc.attr("title"), function(data){
                              inc.replaceWith(data);
                          });
                      });
                      

                      请注意,banner.html 应位于您的其他页面所在的同一域下,否则您的网页将因Cross-Origin Resource Sharing 政策而拒绝banner.html 文件。

                      另外,请注意,如果您使用 JavaScript 加载内容,Google 将无法为其编制索引,因此出于 SEO 原因,这并不是一个好的方法。

                      【讨论】:

                        【解决方案27】:

                        好吧,如果您只想将单独文件中的文本放入页面(文本中的标签也应该可以),您可以这样做(主页上的文本样式—test.html —应该仍然有效):

                        test.html

                        <html>
                        <body>
                        <p>Start</p>
                        
                        <p>Beginning</p>
                        
                        <div>
                        <script language="JavaScript" src="sample.js"></script>
                        </div>
                        
                        <p>End</p>
                        
                        </body>
                        </html>
                        

                        sample.js

                        var data="Here is the imported text!";
                        document.write(data);
                        

                        毕竟,您始终可以自己重新创建您想要的 HTML 标记。除非您想做更多事情,否则需要服务器端脚本来从另一个文件中获取文本。

                        无论如何,我开始使用它的目的是让它,所以如果我更新许多 HTML 文件中常见的描述,我只需要更新一个文件(.js 文件)而不是每个包含文本的 HTML 文件。

                        因此,总而言之,而不是导入 .html 文件,更简单的解决方案是在变量中导入带有 .html 文件内容的 .js 文件(并将内容写入您所在的屏幕调用脚本)。

                        感谢您的提问。

                        【讨论】:

                          【解决方案28】:

                          Here is a great article,您可以实现通用库,只需使用以下代码在一行中导入任何 HTML 文件。

                          <head>
                             <link rel="import" href="warnings.html">
                          </head>
                          

                          你也可以试试Google Polymer

                          【讨论】:

                          • “只需使用下面的代码在一行中导入任何 HTML 文件”是非常虚伪的。然后你必须编写一些 JS 来使用你导入的任何内容,所以它最终不仅仅是“一行”。
                          • HTML 导入已被弃用,并已于 2020 年 2 月从 Chrome 中删除。
                          【解决方案29】:

                          目前没有针对该任务的直接 HTML 解决方案。即使HTML Imports(永久在草稿中)也不会这样做,因为 Import != Include 并且无论如何都需要一些 JS 魔法。
                          我最近写了a VanillaJS script,它只是为了将 HTML 包含到 HTML 中,没有任何复杂性。

                          只需输入您的a.html

                          <link data-wi-src="b.html" />
                          <!-- ... and somewhere below is ref to the script ... -->
                          <script src="wm-html-include.js"> </script>  
                          

                          它是open-source,可能会给出一个想法(我希望)

                          【讨论】:

                            【解决方案30】:

                            如果您使用 django/bootle 之类的框架,他们通常会提供一些模板引擎。 假设您使用bottle,默认模板引擎是SimpleTemplate Engine。 下面是纯html文件

                            $ cat footer.tpl
                            <hr> <footer>   <p>&copy; stackoverflow, inc 2015</p> </footer>
                            

                            您可以在主文件中包含 footer.tpl,例如:

                            $ cat dashboard.tpl
                            %include footer
                            

                            除此之外,您还可以将参数传递给您的 dashborard.tpl。

                            【讨论】:

                              猜你喜欢
                              • 2013-06-25
                              • 1970-01-01
                              • 2016-12-14
                              • 2019-01-04
                              • 2011-01-21
                              • 1970-01-01
                              • 2013-12-01
                              • 2013-06-13
                              • 2011-06-19
                              相关资源
                              最近更新 更多