HTML <template>元素与Javascript模板文字

时间:2018-11-15 02:41:41

标签: javascript web-component template-literals hyperhtml html-templates

Mozilla说Web components包含三种主要技术:

  1. Custom elements
  2. Shadow DOM
  3. HTML templates

根据ECMAscript的Template Literals,数字3是否为“ HTML模板”,甚至是必需的?

看看我从James Milner得到的这个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Web Component</title>
    <script type="text/javascript">
    // We define an ES6 class that extends HTMLElement
    class CounterElement extends HTMLElement{
            constructor() {
                    super();
                    // Initialise the counter value
                    this.counter = 0;

                    // We attach an open shadow root to the custom element
                    const shadowRoot= this.attachShadow({mode: 'open'});

                    // We define some inline styles using a template string
                    const styles=`
                            :host {
                                    position: relative;
                                    font-family: sans-serif;
                            }

                            #counter-increment, #counter-decrement {
                                    width: 60px;
                                    height: 30px;
                                    margin: 20px;
                                    background: none;
                                    border: 1px solid black;
                            }

                            #counter-value {
                                    font-weight: bold;
                            }
                    `;

                    // We provide the shadow root with some HTML
                    shadowRoot.innerHTML = `
                            <style>${styles}</style>
                            <h3>Counter</h3>
                            <slot name='counter-content'>Button</slot>
                            <button id='counter-increment'> - </button>
                            <span id='counter-value'> 0 </span>
                            <button id='counter-decrement'> + </button>
                    `;

                    // We can query the shadow root for internal elements
                    // in this case the button
                    this.incrementButton = this.shadowRoot.querySelector('#counter-increment');
                    this.decrementButton = this.shadowRoot.querySelector('#counter-decrement');
                    this.counterValue = this.shadowRoot.querySelector('#counter-value');

                    // We can bind an event which references one of the class methods
                    this.incrementButton.addEventListener("click", this.decrement.bind(this));
                    this.decrementButton.addEventListener("click", this.increment.bind(this));

            }
            increment() {
                    this.counter++
                    this.invalidate();
            }
            decrement() {
                    this.counter--
                    this.invalidate();
            }
            // Call when the counter changes value
            invalidate() {
                    this.counterValue.innerHTML = this.counter;
            }
    }
    // This is where the actual element is defined for use in the DOM
    customElements.define('counter-element', CounterElement);
    </script>
</head>
<body>
    <counter-element></counter-element>
</body>
</html>

注意他如何不使用HTML模板,而是使用ecmascript模板文字来设置shadowRoot的innerHTML。

此后,他使用querySelector来获取shadowRoot的内部元素,并最终将事件侦听器添加到了递增和递减按钮上。

如果您要使用HTML模板而不是ecmascript模板文字,那么这对您有什么帮助?

从概念上讲,我正在努力寻找一种情况,与Ecmascript模板文字相比,我更喜欢HTML模板元素。

请告知。

1 个答案:

答案 0 :(得分:1)

Web组件本身不需要模板标签。推送HTML Imports时可能更有意义,因为它允许导入和重用HTML代码段,但是此后就停止了。在这里,您可以导入模板并重复使用。

重要的是要注意,这些规范设计为独立的,并且可以相互依赖使用,这使它们通用。 HTML标记具有Web组件范围之外的用例;之所以有用,是因为它允许您定义一段标记,直到稍后通过JavaScript实例化该标记才能呈现。实际上,您可以使用模板而无需使用任何其他规范(自定义元素,Shadow DOM等)。

template标记当然可以与其他规范结合使用。例如,我们可以在所示的示例中使用它来使代码的强制性降低,并更加关注标记,如下所示:

 <template id="counterTemplate">
   <style>
         :host {
             position: relative;
             font-family: sans-serif;
         }

         #counter-increment, #counter-decrement {
             width: 60px;
             height: 30px;
             margin: 20px;
             background: none;
             border: 1px solid black;
          }

         #counter-value {
             font-weight: bold;
         }
   </style>
   <h3>Counter</h3>
   <slot name='counter-content'>Button</slot>
   <button id='counter-increment'> - </button>
   <span id='counter-value'> 0 </span>
   <button id='counter-decrement'> + </button>
</template>

然后在JavaScript中稍后使用它,如下所示:

   const template = document.querySelector('#counterTemplate');
   const counter = document.cloneNode(template);
   shadowRoot.appendChild(counter);

这里的缺点是,由于模板依赖于#counterTemplate模板,因此要求模板在实例化之前就已存在于DOM中。在某些方面,这会使“自定义元素”具有较小的可移植性,因此,为什么可能更希望使用模板文字。我尚未测试两者的性能,但是我的直觉告诉我模板可能会更有效。

免责声明:我写了原始博客文章