Mozilla说Web components包含三种主要技术:
根据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模板元素。
请告知。
答案 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中。在某些方面,这会使“自定义元素”具有较小的可移植性,因此,为什么可能更希望使用模板文字。我尚未测试两者的性能,但是我的直觉告诉我模板可能会更有效。
免责声明:我写了原始博客文章