HTML Templates JavaScript polyfills

后端 未结 4 1693
北荒
北荒 2020-12-31 03:03

I\'m looking for the most standards-compliant / future-proof method for front-end HTML templating.

There exists a relatively new W3C draft specification for HTML Tem

相关标签:
4条回答
  • 2020-12-31 03:06

    There is a jsfiddle that demonstrates such a 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));
    

    As for libraries, and I don't know that they support it yet, but try something like Modernizr and Initializr

    0 讨论(0)
  • 2020-12-31 03:10

    Another possibility are the Web Components polyfills, which include a polyfill for the <template> tag. Keep in mind that webcomponents.js includes polyfills for more than just the <template> tag though.

    0 讨论(0)
  • Xotic750 offered a solid polyfill that works by mutating HTML elements — but it will fail if any new templates are later added to the DOM, and mutation is increasingly discouraged (where avoidable).

    Instead, I recommend introducing the "polyfill" behaviour at the point where you use the templates. Add this function to your 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;
        }
    }
    

    Call the function with a reference to your template element. It'll extract the content, and return a documentFragment that you can then attach to another element (or do whatever else you might want to do with the template content). Like this:

    var template = document.querySelector("template#my-template");
    var content = templateContent(template);
    someElm.appendChild(content);
    

    Now, the other answer didn't mention it, but you probably want some CSS to hide the <template> element.

    template { display: none; }
    

    Here's a CodePen that puts it all together.

    Now, this will work correctly in browsers that natively support the <template> element, and in those that don't. Similar to the other answer, it's not a perfect polyfill, since it doesn't render templates inert (that'd be complex, slow, and error-prone). But it works well enough for me to use in production.

    Leave a comment if you've got questions or issues, and I'll revise accordingly.

    0 讨论(0)
  • 2020-12-31 03:19

    Yet another possibility is Neovov's Template-Element-Polyfill.

    It's a dedicated <template> polyfill that you can find on Github.

    0 讨论(0)
提交回复
热议问题