HTML-шаблоны JavaScript polyfills
Я ищу наиболее стандартизованный/перспективный метод для шаблонов HTML-шаблонов.
Существует относительно новая спецификация черновика W3C для HTML-шаблонов, например:
<template id="mytemplate">
<img src="" alt="great image">
<div class="comment"></div>
</template>
Кто-нибудь знает, существует ли какой-либо хороший JavaScript polyfills, чтобы сделать элемент <template>
применимым в кросс-браузере? Предпочтительно соблюдение этого стандарта.
Трудности
Согласно руководству HTML5Rocks, эти шаблоны имеют следующие свойства:
- "Его содержание эффективно инертно до активации"
- "Script не запускается, изображения не загружаются, звук не воспроизводится,"
- "Содержание считается не в документе"
- "Шаблоны можно размещать в любом месте
<head>
, <body>
или <frameset>
"
Я думаю, что невозможно реализовать все четыре из этих свойств исключительно с помощью JavaScript polyfill, поэтому любое решение будет только частичным.
Ответы
Ответ 1
Существует jsfiddle, который демонстрирует такой polyfill.
<script>
// Shim so we can style in IE6/7/8
document.createElement('template');
</script>
<template id="example">
<h1>
This is template content.
</h1>
<p>
It really great.
</p>
</template>
<div id="target">
<p>
This is regular old content.
</p>
</div>
/* POLYFILL */
(function templatePolyfill(d) {
if('content' in d.createElement('template')) {
return false;
}
var qPlates = d.getElementsByTagName('template'),
plateLen = qPlates.length,
elPlate,
qContent,
contentLen,
docContent;
for(var x=0; x<plateLen; ++x) {
elPlate = qPlates[x];
qContent = elPlate.childNodes;
contentLen = qContent.length;
docContent = d.createDocumentFragment();
while(qContent[0]) {
docContent.appendChild(qContent[0]);
}
elPlate.content = docContent;
}
})(document);
/* EXAMPLE */
var elExample = document.getElementById('example'),
elTarget = document.getElementById('target');
elTarget.appendChild(elExample.content.cloneNode(true));
Что касается библиотек, и я не знаю, что они его поддерживают, но попробуйте что-то вроде Modernizr и Initializr
Ответ 2
Xotic750 предлагает твердотельный polyfill, который работает с помощью мутирования HTML-элементов, но он не сработает, если в DOM будут добавлены новые шаблоны, а мутация будет все больше обескуражена (там, где это можно избежать).
Вместо этого я рекомендую ввести поведение "polyfill" в том месте, где вы используете шаблоны. Добавьте эту функцию в свой JS:
function templateContent(template) {
if("content" in document.createElement("template")) {
return document.importNode(template.content, true);
} else {
var fragment = document.createDocumentFragment();
var children = template.childNodes;
for (i = 0; i < children.length; i++) {
fragment.appendChild(children[i].cloneNode(true));
}
return fragment;
}
}
Вызвать функцию со ссылкой на ваш шаблонный элемент. Он извлечет содержимое и вернет DocumentFragment, который вы затем можете присоединить к другому элементу (или сделайте все, что захотите, с содержимым шаблона). Вот так:
var template = document.querySelector("template#my-template");
var content = templateContent(template);
someElm.appendChild(content);
Теперь другой ответ не упоминал об этом, но вы, вероятно, хотите, чтобы какой-то CSS скрывал элемент <template>
.
template { display: none; }
Здесь CodePen, который ставит все это вместе.
Теперь это будет корректно работать в браузерах, которые поддерживают элемент <template>
, а в тех, которые этого не делают. Подобно другому ответу, это не идеальный polyfill, поскольку он не отображает инертные шаблоны (которые были бы сложными, медленными и подверженными ошибкам). Но он работает достаточно хорошо для меня, чтобы использовать его в производстве.
Оставьте комментарий, если у вас есть вопросы или проблемы, и я буду соответствующим образом пересматривать.
Ответ 3
Другая возможность - это Web Components polyfills, которые включают polyfill для тега <template>
. Имейте в виду, что webcomponents.js включает в себя polyfills больше, чем только тег <template>
.
Ответ 4
Еще одна возможность - Neovov Template-Element-Polyfill.
Это выделенный <template>
polyfill, который вы можете найти в Github.