Incluir otro archivo HTML en un archivo HTML

627

Tengo 2 archivos HTML, supongamos a.htmly b.html. En a.htmlquiero incluir b.html.

En JSF puedo hacerlo así:

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

Significa que dentro del a.xhtmlarchivo, puedo incluir b.xhtml.

¿Cómo podemos hacerlo en el *.htmlarchivo?

lolo
fuente
55
posible duplicado del equivalente de include () en HTML
Wesley Murch
32
¡NO! son 2 cosas diferentes!
lolo
relacionado, pero para localhost: stackoverflow.com/questions/7542872/…
cregox
<object type = "text / html" data = "b.xhtml"> </object>
MarMarAba

Respuestas:

687

En mi opinión, la mejor solución utiliza 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>

Este método es una solución simple y limpia para mi problema.

La .load()documentación de jQuery está aquí .

lolo
fuente
55
¿Cuál es la diferencia de hacer solo este `<script> $ (" # includedContent "). Load (" b.html "); </script>?
Rodrigo Ruiz el
10
@RodrigoRuiz $(function(){})solo se ejecutará cuando el documento termine de cargarse.
ProfK
8
Si el archivo HTML incluido tiene CSS adjunto, puede estropear el estilo de su página.
Omar Jaafor
66
Soy exactamente como has mencionado. Estoy usando bootstrap y tengo sobrescrituras de css para B.html. Cuando uso B.html en A.html para que termine como el encabezado de A.html, puedo ver que el CSS ha perdido su prioridad y tiene un diseño diferente. ¿Alguna solución a esto?
Pavan Dittakavi
38
Esto requiere un servidor . Al usarlo en un archivo local:XMLHttpRequest cannot load file:///.../b.html. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
Basj
155

Ampliando la respuesta de lolo desde arriba, aquí hay un poco más de automatización si tiene que incluir muchos archivos:

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

Y luego incluir algo en el html:

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

Que incluiría el archivo views / header.html y views / footer.html

mhanisch
fuente
Muy útil. ¿Hay alguna manera de pasar un argumento a través de otro parámetro de datos, como data-argumenty recuperarlo en el archivo incluido?
Chris
@chris Puedes usar parámetros GET, por ejemplo$("#postdiv").load('posts.php?name=Test&age=25');
Nam G VU,
55
Pequeña sugerencia: no necesita el class="include"- solo haga su selector jQueryvar includes = $('[data-include]');
jbyrd
no funciona en Chrome con archivos locales "Las solicitudes de origen cruzado solo son compatibles con esquemas de protocolo: htt"
Artem Bernatskyi
2
@ArtemBernatskyi ¿Ayuda en lugar de ejecutar un servidor local? Aquí hay un tutorial fácil: developer.mozilla.org/en-US/docs/Learn/Common_questions/…
mhanisch
146

Mi solución es similar a la de lolo anterior. Sin embargo, inserto el código HTML a través de document.write de JavaScript en lugar de usar 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>\
\
');

La razón por la que no uso jQuery es que jQuery.js tiene un tamaño de ~ 90 kb, y quiero mantener la cantidad de datos para cargar lo más pequeña posible.

Para obtener el archivo JavaScript escapado correctamente sin mucho trabajo, puede usar el siguiente comando sed:

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

O simplemente use el siguiente script práctico de bash publicado como Gist en Github, que automatiza todo el trabajo necesario, convirtiéndolo b.htmla b.js: https://gist.github.com/Tafkadasoh/334881e18cbb7fc2a5c033bfa03f6ee6

Créditos a Greg Minshall por el comando sed mejorado que también escapa a las barras diagonales y comillas simples, que mi comando sed original no consideró.

Alternativamente, para los navegadores que admiten literales de plantilla, lo siguiente también funciona:

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>

`);
Tafkadasoh
fuente
44
@TrevorHickey Sí, tienes razón, ese es el inconveniente de mi solución, y eso no es muy elegante. Sin embargo, como puede insertar una '\' con una expresión regular simple al final de cada línea, esto funciona mejor para mí. Hmm ... tal vez debería agregar a mi respuesta cómo hacer la inserción a través de
expresiones
2
Oh, caramba, eso es feo, no, gracias. Prefiero escribir mi html como html. No me importa si puedo usar sed en la línea de comando; no quiero tener que depender de eso cada vez que cambio el contenido de la plantilla.
jbyrd
1
@Goodra Debería funcionar en cualquier HTML sin 'marcas. Si solo hace una búsqueda / reemplazo para reemplazar ` with \ `ENTONCES, busque / reemplace para reemplazar 'con \'y new-lines con` `new-lines, funcionará bien.
wizzwizz4
1
@ wizzwizz4: Gracias a Greg, el comando sed ahora también escapa a comillas simples y barras diagonales inversas. Además, agregué un script bash que hace todo el trabajo por ti. :-)
Tafkadasoh
1
Puede usar las teclas de retroceso `; luego puede insertar expresiones como ${var}: solo necesita escapar \`y\$
inetphantom
85

Verifique las importaciones HTML5 a través del tutorial Html5rocks y en el proyecto de polímero

Por ejemplo:

<head>
  <link rel="import" href="/path/to/imports/stuff.html">
</head>
usuario1587439
fuente
27
Las importaciones HTML no están destinadas a incluir realmente el contenido en la página directamente. El código en esta respuesta solo está stuff.htmldisponible como plantilla dentro de la página principal, pero tendría que usar secuencias de comandos para crear clones de su DOM en la página principal para que sean visibles para el usuario.
waldyrious
1
Sin embargo, las instrucciones en html5rocks.com para insertar el contenido de una página HTML en otra no parecen funcionar en muchos navegadores. Lo probé en Opera 12.16 y Superbird versión 32.0.1700.7 (233448) sin efecto (en Xubuntu 15.04). Sin embargo, escuché que no funciona en Firefox (debido a un error que, con suerte, se ha solucionado) o en muchas versiones de Chrome. Entonces, aunque parece que puede ser una solución ideal en el futuro, no es una solución de navegador cruzado.
Brōtsyorfuzthrāx
1
Aparentemente no está listo a finales de 2016 en FireFox (45.5.1 ESR). JS consola dice: TypeError: ... .import is undefined. MDN dice "Esta característica no está implementada en ningún navegador de forma nativa en este momento". ¿Alguien sabe si es posible construir FF con esta característica?
sphakka
3
Firefox no lo admitirá. Para habilitarlo, intente configurar "dom.webcomponents.enabled". Solo funcionará en Chrome y Opera, Android con vista web actualizable (startng 4.4.3). Los navegadores de Apple no lo admiten. Parece una buena idea para los componentes web, pero aún no está ampliamente implementada.
Maxim
99
Actualización a finales de 2018: las importaciones de HTML aparentemente están en desuso por alguna razón
V. Rubinetti
60

Plug descarado de una biblioteca que escribí para resolver esto.

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

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

Lo anterior tomará el contenido /path/to/include.htmly lo reemplazará divcon él.

Michael Marr
fuente
44
¿Evaluará esto JavaScript si include.html lo tiene incrustado?
Seth
1
@Seth no parece. Voy a jugar con el src y ver si puedo lograr que lo haga. Gracias a michael-marr
xandout
2
¡¡¡¡Brillante!!!! La suya parece ser la única solución que REEMPLAZA la etiqueta div utilizada como token para saber dónde insertarla. ¡Voy a estudiar la fuente cuidadosamente más tarde! :-)
kpollock
1
gracias esto funciona, incluye el HTML / CSS pero no el Javascript de los archivos fuente. Solo tiene que incluirlo nuevamente donde sea que use el <div data-include="/path/to/include.html"></div>. Esta herramienta hace que sea más fácil hacer una maqueta simple de varias páginas sin plugin de una manera limpia.
Vincent Tang
1
¿Puedo usar esta lib en cualquier aplicación? Quiero decir, ¿cómo se puede acreditar al autor? W3School tiene una solución similar, solo la diferencia es que su código atiende a llamadas recursivas en la carga de la ventana también ... w3schools.com/howto/tryit.asp?filename=tryhow_html_include_1
yeppe
43

Una directiva de inclusión del lado del servidor simple para incluir otro archivo encontrado en la misma carpeta se ve así:

<!--#include virtual="a.html" --> 
Diseño web7 Londres
fuente
21
Necesita configurar su servidor para usar SSI
lolo
77
Aquí hay una referencia para configurar el SSI para su servidor: httpd.apache.org/docs/2.4/howto/ssi.html#configuring
shasi kanth
Podría valer la pena intentarlo <!--#include file="a.html" -->también
jimmyjudas
La inclusión de SSI hace que el servidor web sea un poco más lento (por lo que debe evitarse hasta que sea absolutamente necesario).
Amit Verma
36

No hay necesidad de guiones. No es necesario hacer nada sofisticado en el lado del servidor (aunque probablemente sea una mejor opción)

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

Dado que los navegadores antiguos no son compatibles, debe agregar algunos CSS para solucionarlo:

iframe[seamless] {
    border: none;
}

Tenga en cuenta que para los navegadores que no son compatibles, si hace clic en un enlace en el iframe, el marco irá a esa URL, no a toda la ventana. Una forma de evitarlo es tener todos los enlaces target="_parent", aunque el soporte del navegador es "suficientemente bueno".

bjb568
fuente
77
no parece aplicar estilos CSS desde la página principal, por ejemplo.
Randy
55
@Randy Entonces? Esto podría contarse como un plus (especialmente para contenido generado por el usuario y similares). Puede incluir fácilmente los archivos CSS nuevamente de todos modos sin hacer otra solicitud debido al almacenamiento en caché de todos modos.
bjb568
Respondí a mis necesidades de respuesta a esta pregunta: cómo incluir un archivo html en otro archivo html ...
Grimxn
2
Esa es la mejor respuesta SIN JQuery o scripts. Nice bjb568 gracias!
DBS
12
El seamlessatributo se ha eliminado del borrador HTML del que proviene. No lo uses
Mitja
33

Una solución muy antigua que satisfacía mis necesidades en aquel entonces, pero he aquí cómo hacerlo con un código que cumpla con los estándares:

<!--[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]-->
Aleksandar Vacić
fuente
99
Parece ser que <object>, <embed>y <iframe>todo el trabajo para esto, pero en los tres casos que crear documentos separados con sus propias estilo de scripting y contextos (iframe particular incluye fronteras feos y barras de desplazamiento), y por ejemplo los enlaces por abierta por defecto dentro de ellos y no en el página principal (aunque esto se puede anular con target = "_ parent"). De todos estos, el iframe es el único que tiene la esperanza de integrarse más a través del seamlessatributo HTML5 (mencionado por bjb568), pero aún no está bien soportado: caniuse.com/#feat=iframe-seamless
waldyrious
2
iframe-seamless se ha eliminado del estándar HTML: github.com/whatwg/html/issues/331 . Entonces, el comentario de @waldyrious ya no es correcto (¿te importaría actualizar tu comentario?)
Tomáš Pospíšek
1
Gracias por el aviso, @ TomášPospíšek. Ya no puedo editar mi comentario, pero espero que su respuesta proporcione la advertencia necesaria a los lectores. Para ser claros, la última oración (sobre el seamlessatributo) es la única parte desactualizada; el resto aún se aplica.
waldyrious
17

Como alternativa, si tiene acceso al archivo .htaccess en su servidor, puede agregar una directiva simple que permita interpretar php en los archivos que terminan en la extensión .html.

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

Ahora puede usar un script php simple para incluir otros archivos como:

<?php include('b.html'); ?>
rtd1123
fuente
28
Sí, ese es un muy mal consejo. Los archivos html son estáticos, y apache los sirve muy rápido. Si agrega todos los archivos html al analizador php solo para incluir archivos, tendrá muchos problemas de rendimiento en sus servidores. La forma javascript (jQuery o JS simple) no son soluciones muy buenas, pero aún así son mucho más eficientes y menos peligrosas que esta.
Gfra54
@ Gfra54 ¿Quiere decir que tendremos problemas de rendimiento si usamos Apache solo para esto y no hacemos ningún trabajo de php para el sitio? ¿O se ralentizará si uso php y esta cosa juntos?
user3459110
1
Precaución: Agregar estas líneas .htaccesspuede hacer que las htmlpáginas intenten descargarse como archivos en lugar de verlas en el navegador. Prueba primero. Descargo de responsabilidad: Eso me acaba de pasar cuando probé la solución anterior. Mi .htaccessestaba vacío, excepto por encima de las dos líneas. Precaución aconsejada. Pruebe lolola solución jQuery (a continuación) en su lugar.
cssyphus
hombre, me estaba complicando aunque lo había hecho antes. Gracias por el recordatorio. Para el propósito que necesito, realmente no afecta el rendimiento, así que soy genial.
Gman
Esta respuesta que aplasta el rendimiento es un excelente ejemplo de pensamiento innovador. Nunca lo sugeriría, pero tal vez un salvavidas cuando necesita un poco de martillo php. :-)
moodboom
14

Lo siguiente funciona si el contenido html de algún archivo necesita ser incluido: Por ejemplo, la siguiente línea incluirá el contenido de piece_to_include.html en la ubicación donde se produce la definición de OBJETO.

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

Referencia: http://www.w3.org/TR/WD-html40-970708/struct/includes.html#h-7.7.4

Tío guay
fuente
2
Funciona a la perfección y es la solución más limpia. Esta debería ser la respuesta aceptada.
vbocan
De acuerdo. Solo una nota: no intente hacer una etiqueta de objeto de cierre automático. El texto después se borrará.
Sridhar Sarnobat
Parece crear un nuevo "#documento" que contiene automáticamente nuevas etiquetas anidadas <html> y <body>. Esto no funcionó para mi propósito; mi archivo .html contiene etiquetas <script src = "..." type = "text / javascript">; pero el JS recibió nuevos errores de referencia.
IAM_AL_X
12

Aquí está mi solución en el lugar:

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

Mustafa Burak Kalkan
fuente
1
wow, es más simple
Arian saputra
Solución realmente agradable y simple, gracias ^^
Remling
11

En w3.js incluye trabajos como este:

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

Para una descripción adecuada, mire esto: https://www.w3schools.com/howto/howto_html_include.asp

Kaj Risberg
fuente
Si desea saber cuándo se cargó el documento, puede ponerlo al final del documento: <img src = "thisimagedoesnotexist.dmy" onerror = 'initDocument ()' style = 'display: none;'> Truco inteligente eh?
Kaj Risberg
2
no funciona con google chrome.
deepcell
9

Esto es lo que me ayudó. Para agregar un bloque de código html de b.htmla a.html, esto debería ir en la headetiqueta de a.html:

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

Luego, en la etiqueta del cuerpo, se crea un contenedor con una identificación única y un bloque javascript para cargarlo b.htmlen el contenedor, de la siguiente manera:

<div id="b-placeholder">

</div>

<script>
$(function(){
  $("#b-placeholder").load("b.html");
});
</script>
Ramtin
fuente
66
¿En qué se diferencia esta respuesta de la respuesta aceptada de esta pregunta?
Mohammad Usman
2
@MohammadUsman Aquí el contenedor y el código de JavaScript se encuentran en la etiqueta del cuerpo, mientras que la respuesta aceptada los coloca en la etiqueta de la cabeza y dejando el contenedor solo en la etiqueta del cuerpo.
Ramtin
Esto no vale una nueva respuesta ... es un comentario
Kennet Celeste
8

Sé que esta es una publicación muy antigua, por lo que algunos métodos no estaban disponibles en ese momento. Pero aquí está mi opinión muy simple (basada en la respuesta de Lolo).

Se basa en los atributos de datos * de HTML5 y, por lo tanto, es muy genérico, ya que utiliza la función for-each de jQuery para obtener cada clase.

<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>
Ben Mc
fuente
7

Puede usar un polyfill de Importaciones HTML ( https://www.html5rocks.com/en/tutorials/webcomponents/imports/ ), o esa solución simplificada https://github.com/dsheiko/html-import

Por ejemplo, en la página importa bloque HTML como ese:

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

El bloque puede tener importaciones propias:

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

El importador reemplaza la directiva con el HTML cargado como SSI

Estas directivas se servirán automáticamente tan pronto como cargue este pequeño JavaScript:

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

Procesará las importaciones cuando DOM esté listo automáticamente. Además, expone una API que puede usar para ejecutarse manualmente, obtener registros, etc. Disfruta :)

Dmitry Sheiko
fuente
¿Dónde debe ir la línea del script en el archivo html?
Andrew Truckle
En cualquier lugar dentro del CUERPO. Se puede colocar recursivamente en el contenido de los archivos incluidos
Dmitry Sheiko
¿Probaste esto?
Bhikkhu Subhuti
Seguramente lo hice. En realidad lo he estado usando durante años. ¿Por qué preguntas? Cualquier problema?
Dmitry Sheiko
Entonces, la "clave" de esto es lo script async srcque parece. Probándolo
javadba
6

La mayoría de las soluciones funcionan pero tienen problemas con jquery :

El problema es seguir el código $(document).ready(function () { alert($("#includedContent").text()); } alertas de nada en lugar de alertar al contenido incluido.

Escribo el siguiente código, en mi solución puede acceder al contenido incluido en $(document).ready función:

(La clave está cargando el contenido incluido sincrónicamente).

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 incluye plugin en github

Amir Saniyan
fuente
Al usar esto y luego ver la fuente de la página desde un navegador, solo verá el script. ¿No afecta esto a la capacidad de los motores de búsqueda para analizar su sitio, destruyendo en última instancia cualquier esfuerzo de SEO?
hmcclungiii
Sí, este método destruye cualquier SEO :)
Amir Saniyan
Por otra parte, todos los métodos basados ​​en JavaScript lo hacen.
wizzwizz4
5

Para insertar contenido del archivo nombrado:

<!--#include virtual="filename.htm"-->
St.Eve
fuente
1
usando paréntesis angulares para []: [! - # include virtual = "include_omega.htm" -]
St.Eve
4

¡La respuesta de Athari (la primera!) Fue demasiado concluyente! ¡Muy bien!

Pero si desea pasar el nombre de la página para que se incluya como parámetro de URL , esta publicación tiene una solución muy buena para combinar con:

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

Entonces se convierte en algo como esto:

Su URL:

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

El código a.html ahora se convierte en:

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

¡Funcionó muy bien para mí! Espero haber ayudado :)

Massa
fuente
Problema de seguridad, porque puede enviar a alguien este enlace: www.yoursite.com/a.html?p=htttp://www.linktovir.us/here.html
JoostS
4

html5rocks.com tiene un muy buen tutorial sobre estas cosas, y esto podría ser un poco tarde, pero yo mismo no sabía que existía. w3schools también tiene una manera de hacer esto usando su nueva biblioteca llamada w3.js. La cuestión es que esto requiere el uso de un servidor web y un objeto HTTPRequest. En realidad, no puede cargarlos localmente y probarlos en su máquina. Sin embargo, lo que puede hacer es usar polyfills provistos en el enlace html5rocks en la parte superior, o seguir su tutorial. Con un poco de magia JS, puedes hacer algo como esto:

 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);
 }

Esto hará que el enlace (puede cambiar para ser el elemento de enlace deseado si ya está configurado), establecer la importación (a menos que ya lo tenga) y luego agregarlo. Luego, a partir de ahí, tomará eso y analizará el archivo en HTML, y luego lo agregará al elemento deseado bajo un div. Todo esto se puede cambiar para adaptarse a sus necesidades desde el elemento adjunto hasta el enlace que está utilizando. Espero que esto haya ayudado, puede ser irrelevante ahora si han surgido formas más nuevas y más rápidas sin usar bibliotecas y marcos como jQuery o W3.js.

ACTUALIZACIÓN: Esto arrojará un error que indica que la importación local ha sido bloqueada por la política CORS. Es posible que necesite acceso a la web profunda para poder usar esto debido a las propiedades de la web profunda. (Es decir, sin uso práctico)

SubLock69
fuente
4

Aquí está mi enfoque usando Fetch API y función asíncrona

<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>
barro32
fuente
3

No hay una solución HTML directa para la tarea por ahora. Incluso las importaciones HTML (que está permanentemente en borrador ) no harán el trabajo, porque Importar = Incluir y se requerirá algo de magia JS de todos modos.
Recientemente escribí un script VanillaJS que es solo para incluir HTML en HTML, sin ninguna complicación.

Simplemente colóquelo en su a.html

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

Es open-sourcey puede dar una idea (espero)

al.scvorets
fuente
3

Puede hacerlo con la biblioteca jQuery de JavaScript de esta manera:

HTML:

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

JS:

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

Tenga en cuenta que banner.htmldebe ubicarse en el mismo dominio en el que se encuentran sus otras páginas; de lo contrario, sus páginas web rechazarán el banner.htmlarchivo debido a las políticas de intercambio de recursos de origen cruzado .

Además, tenga en cuenta que si carga su contenido con JavaScript, Google no podrá indexarlo, por lo que no es exactamente un buen método por razones de SEO.

AndrewL64
fuente
2

¿Probaste una inyección de iFrame?

Inyecta el iFrame en el documento y se elimina a sí mismo (se supone que debe estar en el DOM HTML)

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

Saludos

Alban Lusitanae
fuente
1

Llegué a este tema buscando algo similar, pero un poco diferente del problema planteado por lolo. Quería construir una página HTML con un menú alfabético de enlaces a otras páginas, y cada una de las otras páginas podría o no existir, y el orden en que se crearon podría no ser alfabético (ni siquiera numérico). Además, como Tafkadasoh, no quería hinchar la página web con jQuery. Después de investigar el problema y experimentar durante varias horas, esto es lo que funcionó para mí, con comentarios relevantes agregados:

<!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 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>
vernonner3voltazim
fuente
1

Aquí hay un gran artículo , puede implementar una biblioteca común y simplemente usar el siguiente código para importar cualquier archivo HTML en una línea.

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

También puedes probar Google Polymer

Dhiral Pandya
fuente
66
"simplemente use el código a continuación para importar cualquier archivo HTML en una línea" es bastante falso. Luego debe escribir un poco de JS para hacer uso de cualquier contenido que haya importado, de modo que termine siendo mucho más que "una línea".
skybondsor
1

Uso de backticks de ES6 ``: ¡ literales de plantilla !

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

` 
<div id="more"></div>

De esta forma podemos incluir html sin comillas de codificación, incluir variables del DOM, etc.

Es un poderoso motor de plantillas, podemos usar archivos js separados y usar eventos para cargar el contenido en su lugar, o incluso separar todo en fragmentos y llamadas a pedido:

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

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

NVRM
fuente
1
Buen ejemplo: ¿por qué no hay votos a favor (hasta ahora)?
javadba
Oye, tienes razón, en 2018 lo anterior fue una clara señal de un buen RTFM real;) Rompí en gran medida esa javascriptinsignia como programador de pasatiempos hasta entonces.
NVRM
1

Para que la Solución funcione, debe incluir el archivo csi.min.js, que puede ubicar aquí .

Según el ejemplo que se muestra en GitHub, para usar esta biblioteca debe incluir el archivo csi.js en el encabezado de su página, luego debe agregar el atributo de inclusión de datos con su valor establecido en el archivo que desea incluir, en el contenedor elemento.

Ocultar código de copia

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

... Espero eso ayude.

Hamza Ali
fuente
0

PHP es un lenguaje de script de nivel de servidor. Puede hacer muchas cosas, pero un uso popular es incluir documentos HTML dentro de sus páginas, lo mismo que SSI. Al igual que SSI, esta es una tecnología de nivel de servidor. Si no está seguro de tener la funcionalidad PHP en su sitio web, póngase en contacto con su proveedor de alojamiento.

Aquí hay un script PHP simple que puede usar para incluir un fragmento de HTML en cualquier página web habilitada para PHP:

Guarde el HTML para los elementos comunes de su sitio para separar los archivos. Por ejemplo, su sección de navegación podría guardarse como navigation.html o navigation.php. Use el siguiente código PHP para incluir ese HTML en cada página.

<?php require($DOCUMENT_ROOT . "navigation.php"); ?>

Use el mismo código en cada página que desee incluir el archivo. Asegúrese de cambiar el nombre del archivo resaltado por el nombre y la ruta a su archivo de inclusión.

Udara Pathirage
fuente
0

Si usa algún marco como django / bootle, a menudo envían algún motor de plantillas. Digamos que usa botella, y el motor de plantilla predeterminado es SimpleTemplate Engine . Y a continuación se muestra el archivo html puro

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

Puede incluir el footer.tpl en su archivo principal, como:

$ cat dashboard.tpl
%include footer

Además de eso, también puede pasar parámetros a su dashborard.tpl.

jaseywang
fuente
0

Basado en la respuesta de https://stackoverflow.com/a/31837264/4360308 , he implementado esta funcionalidad con Nodejs (+ express + cheerio) de la siguiente manera:

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($);
        ...
    }
}

agregar -> incluye el contenido en el div

reemplazar -> reemplaza el div

fácilmente podría agregar más comportamientos siguiendo el mismo diseño

giroxiii
fuente