HTML-шаблоны JavaScript polyfills - программирование
Подтвердить что ты не робот

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, поэтому любое решение будет только частичным.

4b9b3361

Ответ 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.