Включить другой файл HTML в файл HTML

У меня есть 2 файла HTML, предположим a.html а также b.html, В a.html Я хочу включить b.html,

В JSF я могу сделать это так:

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

Это значит что внутри a.xhtml файл, я могу включить b.xhtml,

Как мы можем сделать это в *.html файл?

46 ответов

Решение

На мой взгляд, лучшее решение использует 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() документация здесь.

Расширяя ответ lolo сверху, здесь есть немного больше автоматизации, если вам нужно включить много файлов:

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

А затем включить что-то в HTML:

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

Который будет включать в себя файлы views/header.html и views/footer.html

Мое решение похоже на приведенное выше. Тем не менее, я вставляю HTML-код через JavaScript document.write вместо использования 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 составляет ~90 КБ, и я хочу, чтобы объем загружаемых данных был как можно меньшим.

Чтобы получить правильно экранированный файл JavaScript без особых усилий, вы можете использовать следующую команду sed:

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

Или просто используйте следующий удобный скрипт bash, опубликованный как Gist на Github, который автоматизирует всю необходимую работу, конвертируя b.html в b.js: https://gist.github.com/Tafkadasoh/334881e18cbb7fc2a5c033bfa03f6ee6

Благодарность Greg Minshall за улучшенную команду sed, которая также избегает обратной косой черты и одинарных кавычек, которые моя первоначальная команда sed не учитывала.

Оформить заказ импорта HTML5 с помощью учебника Html5rocks и в Polymer -Project

Например:

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

Бесстыдная заглушка библиотеки, которую я написал, решает эту проблему.

https://github.com/LexmarkWeb/csi.js

<div data-include="/path/to/include.html"></div>

Выше будет принимать содержимое /path/to/include.html и заменить div с этим.

Нет необходимости в скриптах. Нет необходимости делать какие-то модные вещи на стороне сервера (хотя это, вероятно, будет лучшим вариантом)

<iframe src="/path/to/file.html" seamless></iframe>

Поскольку старые браузеры не поддерживают бесшовные, вы должны добавить некоторые CSS, чтобы исправить это:

iframe[seamless] {
    border: none;
}

Имейте в виду, что для браузеров, которые не поддерживают бесшовные, если вы нажмете на ссылку в iframe, это заставит фрейм перейти к этому URL, а не ко всему окну. Способ обойти это состоит в том, чтобы иметь все ссылки target="_parent"Тем не менее, поддержка браузера "достаточно хороша".

Простая серверная директива include для включения другого файла, найденного в той же папке, выглядит следующим образом:

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

Очень старое решение, которое я тогда удовлетворял своим потребностям, но вот как сделать это в соответствии со стандартами:

<!--[if IE]>
<object classid="clsid:25336920-03F9-11CF-8FD0-00AA00686F13" data="some.html">
<p>backup content</p>
</object>
<![endif]-->

<!--[if !IE]> <-->
<object type="text/html" data="some.html">
<p>backup content</p>
</object>
<!--> <![endif]-->

Вот мое решение на месте:

(() => {
    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>

Если требуется включить html-контент из какого-либо файла, выполните следующие действия: Например, следующая строка будет содержать содержимое файла piece_to_include.html в месте, где происходит определение OBJECT.

...text before...
<OBJECT data="file_to_include.html">
Warning: file_to_include.html could not be included.
</OBJECT>
...text after...

Ссылка: http://www.w3.org/TR/WD-html40-970708/struct/includes.html

В w3.js include работает так:

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

В качестве альтернативы, если у вас есть доступ к файлу.htaccess на вашем сервере, вы можете добавить простую директиву, которая позволит интерпретировать php для файлов, заканчивающихся расширением.html.

RemoveHandler .html
AddType application/x-httpd-php .php .html

Теперь вы можете использовать простой PHP-скрипт для включения других файлов, таких как:

<?php include('b.html'); ?>

Это то, что помогло мне. Для добавления блока HTML-кода из b.html в a.htmlэто должно идти в head тег a.html:

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

Затем в теге body создается контейнер с уникальным идентификатором и блоком javascript для загрузки b.html в контейнер следующим образом:

<div id="b-placeholder">

</div>

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

Я знаю, что это очень старый пост, поэтому некоторые методы не были доступны тогда. Но вот мой очень простой взгляд на это (основываясь на ответе Лоло).

Он опирается на атрибуты data- * HTML5 и, следовательно, очень универсален, поскольку использует функцию jQuery for-each для получения каждого.class, соответствующего "load-html", и использует соответствующий ему атрибут "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>

Вы можете использовать полизаполнение HTML Imports ( https://www.html5rocks.com/en/tutorials/webcomponents/imports/) или это упрощенное решение 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, который вы можете использовать для запуска вручную, для получения журналов и так далее. Наслаждаться:)

Большинство решений работает, но у них есть проблема с jquery:

Проблема заключается в следующем коде $(document).ready(function () { alert($("#includedContent").text()); } ничего не предупреждает вместо того, чтобы предупредить включенный контент.

Я пишу код ниже, в моем решении вы можете получить доступ к включенному контенту в $(document).ready функция:

(Ключ загружает включенный контент синхронно).

index.htm:

<html>
    <head>
        <script src="jquery.js"></script>

        <script>
            (function ($) {
                $.include = function (url) {
                    $.ajax({
                        url: url,
                        async: false,
                        success: function (result) {
                            document.write(result);
                        }
                    });
                };
            }(jQuery));
        </script>

        <script>
            $(document).ready(function () {
                alert($("#test").text());
            });
        </script>
    </head>

    <body>
        <script>$.include("include.inc");</script>
    </body>

</html>

include.inc:

<div id="test">
    There is no issue between this solution and jquery.
</div>

JQuery включает плагин на GitHub

Вот мой подход с использованием 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>

Веб-компоненты

Создаю следующий веб-компонент, похожий на JSF

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

Вы можете использовать его как обычный тег html на своих страницах (после добавления фрагмента кода 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>

Используйте includeHTML (наименьшая js-lib: ~150 строк)

Загрузка HTML-частей через HTML-тег (чистый js)
Поддерживаемая загрузка: асинхронная / синхронизация, любая глубокая рекурсивная включает

Поддерживаемые протоколы: http: //, https: //, file: ///
Поддерживаемые браузеры: IE 9+, FF, Chrome (а могут быть и другие)

ПРИМЕНЕНИЕ:

1.Вставьте includeHTML в раздел заголовка (или перед тегом закрытия тела) в файле HTML:

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

2. везде используйте includeHTML в качестве тега HTML:

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

Другой подход с использованием 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>

Чтобы вставить содержимое именованного файла:

<!--#include virtual="filename.htm"-->

Вы пробовали внедрение iFrame?

Он вставляет iFrame в документ и удаляет себя (предполагается, что он находится в HTML DOM)

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

С уважением

Ни одно из этих решений не соответствует моим потребностям. Я искал что-то более похожее на PHP. Это решение довольно простое и эффективное, на мой взгляд.

include.js->

      void function(script) {
    const { searchParams } = new URL(script.src);
    fetch(searchParams.get('src')).then(r => r.text()).then(content => {
        script.outerHTML = content;
    });
}(document.currentScript);

index.html->

      <script src="/include.js?src=/header.html">
<main>
    Hello World!
</main>
<script src="/include.js?src=/footer.html">

Простые настройки могут быть сделаны для создания ,require, иrequire_once, которые могут быть полезны в зависимости от того, что вы делаете. Вот краткий пример того, как это может выглядеть.

include_once->

      var includedCache = includedCache || new Set();
void function(script) {
    const { searchParams } = new URL(script.src);
    const filePath = searchParams.get('src');
    if (!includedCache.has(filePath)) {
        fetch(filePath).then(r => r.text()).then(content => {
            includedCache.add(filePath);
            script.outerHTML = content;
        });
    }
}(document.currentScript);

Надеюсь, поможет!

html5rocks.com имеет очень хороший учебник по этому материалу, и это может быть немного поздно, но я сам не знал, что это существовало. У w3schools также есть способ сделать это, используя их новую библиотеку w3.js. Дело в том, что это требует использования веб-сервера и объекта HTTPRequest. Вы не можете загрузить их локально и проверить их на своей машине. Однако вы можете использовать полифилы, указанные в ссылке html5rocks вверху, или следовать их руководству. Немного волшебства 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. Может потребоваться доступ к Deep Web, чтобы иметь возможность использовать это из-за свойств Deep Web. (Это означает, что нет практического использования)

Ответ Атари (первый!) Был слишком убедительным! Отлично!

Но если вы хотите передать имя страницы для включения в качестве параметра URL, этот пост имеет очень хорошее решение, которое можно использовать в сочетании с:

http://www.jquerybyexample.net/2012/06/get-url-parameters-using-jquery.html

Так это становится примерно так:

Ваш URL:

www.yoursite.com/a.html?p=b.html

Код a.html теперь становится:

<html> 
  <head> 
    <script src="jquery.js"></script> 
    <script> 
    function GetURLParameter(sParam)
    {
      var sPageURL = window.location.search.substring(1);
      var sURLVariables = sPageURL.split('&');
      for (var i = 0; i < sURLVariables.length; i++) 
      {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] == sParam) 
        {
            return sParameterName[1];
        }
      }
    }​
    $(function(){
      var pinc = GetURLParameter('p');
      $("#includedContent").load(pinc); 
    });
    </script> 
  </head> 

  <body> 
     <div id="includedContent"></div>
  </body> 
</html>

Это сработало очень хорошо для меня! Надеюсь помогло:)

Прямого HTML-решения для этой задачи пока нет. Даже HTML-импорт (который постоянно находится в черновике) не сработает, потому что Import!= Include, и в любом случае потребуется некоторое волшебство JS.
Недавно я написал сценарий VanillaJS, предназначенный только для включения 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 и может дать идею (я надеюсь)

Вы можете сделать это с помощью библиотеки jQuery JavaScript следующим образом:

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 должны находиться в том же домене, в котором находятся другие ваши страницы, в противном случае ваши веб-страницы будут отклонять banner.html файл из-за политики общего доступа к ресурсам.

Также обратите внимание, что если вы загрузите свой контент с помощью JavaScript, Google не сможет проиндексировать его, поэтому это не совсем хороший метод по причинам SEO.

Здесь есть несколько типов ответов, но я так и не нашел самый старый из используемых здесь инструментов:

«И все остальные ответы у меня не работали».

      <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>

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>
<div><h2>Hello World</h2></div>
</body>

Чтобы решение заработало, вам необходимо включить файл csi.min.js, который вы можете найти здесь.

В соответствии с примером, показанным на GitHub, чтобы использовать эту библиотеку, вы должны включить файл csi.js в заголовок вашей страницы, затем вам нужно добавить атрибут data-include со значением, установленным в файл, который вы хотите включить, в контейнер. элемент.

Скрыть код копирования

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

... Надеюсь, это поможет.

Другие вопросы по тегам