HTML模板JavaScript polyfill

Rob*_*low 16 javascript html5 w3c polyfills html5-template

我正在寻找最符合标准/面向未来的前端HTML模板方法.

HTML模板存在一个相对较新的W3C草案规范,例如:

<template id="mytemplate">
    <img src="" alt="great image">
    <div class="comment"></div>
</template>
Run Code Online (Sandbox Code Playgroud)

有没有人知道是否已经存在任何好的JavaScript polyfill使 <template>元素可以跨浏览器方式使用?最好符合本标准.


难点

根据HTML5Rocks指南,这些模板具有以下属性:

  • "它的内容在激活之前是有效的惰性"
  • "脚本无法运行,图像无法加载,音频无法播放"
  • "内容被认为不在文件中"
  • "模板可放置在任何地方内的<head>,<body><frameset>"

我认为用JavaScript polyfill纯粹实现所有这四个属性是不可能的,因此任何解决方案都只是部分解决方案.

iva*_*ese 10

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

通过引用模板元素来调用该函数.它将提取内容,并返回一个documentFragment,然后您可以将其附加到另一个元素(或者执行您可能想要对模板内容执行的任何操作).像这样:

var template = document.querySelector("template#my-template");
var content = templateContent(template);
someElm.appendChild(content);
Run Code Online (Sandbox Code Playgroud)

现在,另一个答案没有提到它,但你可能想要一些CSS来隐藏<template>元素.

template { display: none; }
Run Code Online (Sandbox Code Playgroud)

这是一个将所有内容组合在一起的CodePen.

现在,这将在本机支持该<template>元素的浏览器中正常工作,而在那些不支持元素的浏览器中也能正常工作.与其他答案类似,它不是一个完美的polyfill,因为它不会使模板呈现惰性(复杂,缓慢且容易出错).但它足以让我在生产中使用.

如果您有疑问或问题,请发表评论,我会相应地进行修改.


Xot*_*750 9

有一个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's 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));
Run Code Online (Sandbox Code Playgroud)

至于图书馆,我不知道他们支持它,但尝试类似ModernizrInitializr