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

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

Mozilla 说 Web components由三项主要技术组成:

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

是第 3 项,“HTML 模板”,根据 ECMAscript 的 Template Literals 甚至是必要的?

看看我从 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 模板文字,这对您有什么好处?

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

请指教。

最佳答案

模板标签对于 Web 组件本身并不是“必需的”。当 HTML Imports 时可能更有意义正在插入,允许导入和重用 HTML 片段,但此后已停止。在这里您可以导入一个模板并重新使用它。

重要的是要注意这些规范是独立设计的,也可以相互依赖地使用,这使得它们具有通用性。 HTML 标签在 Web 组件领域之外有用例;它很有用,因为它允许您定义一段标记,该标记在稍后通过 JavaScript 实例化之前不会呈现。事实上,您可以在不使用任何其他规范(自定义元素、Shadow DOM 等)的情况下使用模板。

模板标签当然可以与其他规范一起使用。例如,我们可以在所示示例中使用它来使代码的命令性降低,而使标记更加集中,如下所示:

 <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);

这里的缺点是它需要模板在实例化之前存在于 DOM 中,因为它依赖于 #counterTemplate 模板。在某些方面,这会降低自定义元素的可移植性,因此模板文字可能更受欢迎。我没有测试过两者的性能,但我的直觉告诉我,该模板的性能可能更高。

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

关于javascript - HTML <template> 元素与 Javascript 模板文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53311660/

相关文章:

javascript - Google 图表和 Ajax 响应

javascript - 简单的 Redux 计数器组件实现

javascript - 如何在 React js 中的模板文字中调用 onclick 函数

javascript - 另一个 React 组件中的新 React 模块

javascript - 当用户离开页面时,React 路由器组件不会销毁

ecmascript-6 - 使用带有不受信任字符串的模板文字设置属性值时,是否存在 XSS 风险?

javascript - 模板文字内的循环?

javascript - Firebase 和 Algolia 确保搜索没有搜索命中

JavaScript 从文本渲染 SVG

javascript - 了解 Polymer 事件和带有嵌套元素的数据绑定(bind)?