Включить другой файл 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>
Вот мой подход с использованием 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
и мы в фокусе
но рассмотрим нижеприведенный случай
- 🧾 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>
... Надеюсь, это поможет.