Нова специфікація «HTML Imports» описує, як вставити один документ в інший за допомогою HTML-тега <link rel = "import">.
Зараз можна вставляти документ в документ за допомогою <iframe>. Навіщо ж потрібен ще якийсь імпорт і що не так з <iframe>?
З <iframe> все так. Однак, за своїм змістом <iframe> - це окремий документ. Для <iframe> створюється повністю своє оточення, у нього свій об'єкт window і свої змінні. Якщо <iframe> завантажений з іншого домену, то взаємодія з ним можлива тільки через postMessage.
Такий варіант зручний тільки тоді, коли потрібно в одній сторінці відобразити вміст іншої. У випадку коли потрібно вбудувати інший документ з єдиним скриптовим простором, єдиними стилями як природну частину поточного, то краще використати <link rel = "import">.
<link rel = "import"> - це аналог <script>, але для підключення повноцінних документів з шаблонами, бібліотеками, веб-компонентами і т.д.
Синтаксис
<link rel="import" href="http://site.com/document.html">
На відміну від <iframe>, тег <link rel = "import"> може бути в будь-якому місці документа, навіть в <head>. При вставці через <iframe> документ показується всередині фрейму. У випадку з <link rel = "import"> це не так, за замовчуванням документ взагалі не показується.
HTML, завантажений через <link rel = "import"> має окремий DOM документа, але скрипти в ньому виконуються в загальному контексті сторінки. Файл обробляється, виконуються скрипти, будується DOM документа, але не показується, а записується в властивість link.import.
Ви самі вирішуєте, де і коли його вставити. У прикладі нижче <link rel = "import" href = "timer.html"> підключає документ timer.html і, після його завантаження викликає функцію show. Ця функція через link.import.querySelector ('time') вибирає потрібну частину з підвантаженими документа і вставляє її в поточний:
<!DOCTYPE HTML>
<html>
<body>
<script>
function show() {
var time = link.import.querySelector('time')
document.body.appendChild(time);
};
</script>
<link rel="import" id="link" onload="show()" href="timer.html">
</body>
</html>
У файлі timer.html знаходиться елемент і скрипт, який його «оживляє»:
<!DOCTYPE HTML>
<html>
<body>
<time id="timer">0</time>
<script>
var localDocument = document.currentScript.ownerDocument;
var timer = localDocument.getElementById('timer');
var timerId = setInterval(function() {
timer.innerHTML++;
}, 1000);
</script>
</body>
</html>
Важливі моменти
Після завантаження всі скрипти в підключеному timer.html виконуються в контексті основної сторінки, так що timer і інші змінні стануть глобальними змінними сторінки.
Мінливий document - це документ головної сторінки. Для доступу до імпортованого, тобто поточного документа зсередини timer.html його можна отримати як document.currentScript.ownerDocument.
Таймер в завантаженому документі починає працювати відразу, новий документ оживає відразу після завантаження, хоча до перенесення вузлів в основний документ цього може бути і не видно.
В наведеному вище прикладі вмістом імпорту керував основний документ, але timer.html міг би і показати сам себе викликом document.body.appendChild (timer) або викликати функцію з зовнішнього документа, так як у них єдина область видимості. Тоді не знадобився б ніякий onload.
Зверніть увагу на те, що стилі імпорту потрапляють в контекст сторінки. В наведеному вище прикладі імпорт додав і стиль для #timer і сам елемент.
Веб-компоненти
Імпорт задуманий як частина платформи Web Components. Передбачається, що головний документ може імпортувати файли-визначення, в яких будуть всі необхідні HTML, JS і CSS для елементів, а потім використовувати їх. Приклад:
<link rel = "import" href = "ui-tabs.html">
<link rel = "import" href = "ui-dialog.html">
<ui-tabs> ... </ ui-tabs>
<ui-dialog> ... </ ui-dialog>
Повторне використання
Повторний імпорт з тим же URL використовує вже існуючий документ. Якщо файл libs.html імпортований два рази, то CSS і скрипти з нього підключаються і будуть виконуватися рівно один раз.
Це можна використовувати, щоб не довантажувати однакові залежності багато разів. Сама сторінка та її обсяги імпорту, їх підімпорти, і так далі, можуть підключати libs.html без побоювання зайвий раз перезавантажити і виконати скрипти.
Наприклад:
Головний файл index.html підключає документи:
<link rel = "import" href = "ui-tabs.html">
<link rel = "import" href = "ui-dialog.html">
ui-tabs.html підключає libs.html:
<link rel = "import" href = "libs.html">
... template і код для табів ...
ui-dialog.html також використовує libs.html:
<link rel = "import" href = "libs.html">
... template і код для діалогів ...
Файл libs.html при цьому буде підключений тільки один раз. Це дозволяє не боятися зайвого дублювання бібліотек, використовуваних при описі безлічі компонентів.
Висновки
Тег <link rel = "import"> дозволяє підключити будь-який документ на сторінку.
Скриптовий простір і стилі зі сторінкою будуть загальні.
Документ DOM - окремий, він доступний як link.import зовні, так і з внутрішнього скрипта - через document.currentScript.ownerDocument. Можна без проблем переносити елементи з головного документа в імпорт і навпаки.
Обсяги імпорту можуть містити інші обсяги імпорту.
Якщо якийсь URL імпортуєть ся повторно - підключається вже готовий документ, без повторного виконання скриптів в ньому. Це дозволяє уникнути дублювання при використанні однієї бібліотеки у багатьох місцях.