Подключение html

Есть файл import.html:

<template>
  <h1>Hello World!</h1>
  <!-- Img is not requested until the <template> goes live. -->
  <script>alert("Executed when the template is activated.");</script>
</template>

И файл index.html в который он включается:

<!DOCTYPE html>
<html lang="en">
  <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <meta name="theme-color" content="#111111">

    <link rel="import" href="import.html">
                
        <title>What are HTML imports and how do they work</title>
        
  </head>
  <body>
    <h1>Hello from Designmodo</h1>
        <div id="container"></div>

    <script>
var link = document.querySelector('link[rel="import"]');
var template = link.import.querySelector('template');
var clone = document.importNode(template.content, true);
document.querySelector('#container').appendChild(clone);
            console.log("test")
    </script>
 
  </body>
</html>

При этом отладчик выдаёт ошибку:

Uncaught TypeError: link.import is undefined

на строку var template = link.import.querySelector('template');


Ответы (1 шт):

Автор решения: Daniil Loban

Если очень захотеть, то реализовать импорт можно самостоятельно. Разумеется что тут это полноценно продемонстировать не получится поэтому просто оставлю содержимое двух файлов в конце, а ниже снипет с некоторыми правками чтобы работало прямо тут:

// содержимое файла (для снипета)
const importHTML = `<div><h1>Hello World!<\/h1><script>alert("Executed when the template is activated.");<\/script><\/div>`

// эмулируем  загрузку (для снипета)
const loadIFrame = () => {
  document.querySelector('iframe').src = 'data:text/html,' + encodeURIComponent(importHTML)
}

loadIFrame()

const iframe = document.querySelector('iframe')
iframe.onload = function() {
  const content = importHTML // хак (для снипета)
  const clone = document.createElement('div');
  clone.innerHTML = content; 
  document.querySelector('#container').appendChild(clone);
  iframe.remove() 
}
<title>What are HTML imports and how do they work</title>

<h1>Hello from Designmodo</h1>
<div id="container"></div>
<iframe style="display:none" src=""></iframe>

Основная фишка - использование спрятанного iframe и события onload можно сделать так чтобы страница вставлялась именно на место iframe через outerHTML тогда и кода в onload меньше:

const content = this.contentWindow.document.body.innerHTML 
iframe.outerHTML = content

Тег <template> был заменен на div чтобы вставленное было видно и alert срабатывал.

import.html

<div>
  <h1>Hello World!</h1>
  <!-- Img is not requested until the <template> goes live. -->
  <script>alert("Executed when the template is activated.");</script> 
</div>

К сожалению с documentFragment данный трюк выполнить не получается, поэтому создается несколько избыточная вложенность:

<div id="container">
  <div>
    <div>
      <h1>Hello World!</h1>
      <!-- Img is not requested until the <template> goes live. -->
      <script>alert("Executed when the template is activated.");</script> 
    </div>
  </div>
</div>

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
        <meta charset="UTF-8">
        <title>What are HTML imports and how do they work</title>
  </head>
  <body>
    <h1>Hello from Designmodo</h1>
    <div id="container"></div>
    <iframe style="display:none" src="import.html"></iframe>

    <script>
      const iframe = document.querySelector('iframe')
      iframe.onload = function() {
        // получаем содержимое body в iframe
        const content = this.contentWindow.document.body.innerHTML 
        // const clone = document.createDocumentFragment() не работает
        const clone = document.createElement('div');
        clone.innerHTML = content; 
        document.querySelector('#container').appendChild(clone);
        iframe.remove() 
      }
    </script>
  </body>
</html>
→ Ссылка