Use of Template with HTML Custom Elements

后端 未结 2 1893
面向向阳花
面向向阳花 2020-11-30 12:59

I just started learning about the HTML custom elements, and through reading a series of intros, tutorials, and documentation, I think I have a good handle on how it works, b

相关标签:
2条回答
  • 2020-11-30 13:17

    Disclaimer: I'm an author of the rich-component library mentioned below.

    After some time of experimenting with custom elements and recently raising a full blown project based solely upon them I'd like to share my insights on this:

    • any component tiny as it is, is a candidate to grow to some beast
    • HTML part of it may grow to a point where it is very non-convenient to keep it within JS
    • do use template, built and parsed once and from that point cloned and injected into the shadow root - this is the same best practice as to use document fragment instead of mutating a living DOM
    • if the template contents should be changed from component's instance to instance - some kind of data binding framework may be used, and if minimalist approach on those is taken - it might still be easier and more performant to deal with a cloned-from-template document fragment than operate on string or template literals

    In order to not write the same dozens of lines over and over again I've prepared rich-component library, which:

    • normalizes some API for template provisioning and all those 'clone template, create shadow, inject template's content into it' lines of repeating code
    • known to fetch html contents when html URL is provided
    • caches the templates so the fetch is done only once
    0 讨论(0)
  • 2020-11-30 13:44

    Actually <template> elements can be imported from another document via HTML Imports, along with the Javascript code that will define the custom element:

    <link rel="import" src="my-custom-element.html">
    ...
    <custom-element></custom-element>
    

    So it doesn't need to be included in a every HTML document. This post shows a minimal example.

    HTML Imports are implemented only in Chrome and Opera. If you want to use them in the with Firefox and Safari you'll need to use the HTML Imports polyfill.

    On the other hand and for the moment, Mozilla and Apple don't intend to implement HTML Imports natively in their respective browsers. Therefore they recommend to define custom elements with pure Javascript modules (with import or <script src="...">), and promote template literals strings instead, which offer some advantages (variables, functions), but are sometimes more complicated to code in an IDE (because of their string representation).

    Maybe in the future standard HTML modules will be adopted by all browsers, and <template> will come back in the spotlight...

    Note that without HTML Imports you can still import yourself some HTML documents with fetch():

    fetch( "template.html" )
        .then( stream => stream.text() )
        .then( text => 
            customElements.define( "c-e", class extends HTMLElement {
                constructor() {
                    super()
                    this.attachShadow( { mode: 'open'} )
                        .innerHTML = text
                }
            } )
        )
    

    Update 2019

    HTML Imports won't be supported natively after Chrome 73. You should then use the other solutions listed above (the polyfill, an alternate module loader, JS import, or a direct download with fetch).

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