Lon*_*est 7 javascript web-component template-literals hyperhtml html-templates
Mozilla 表示Web 组件由三种主要技术组成:
根据 ECMAscript 的模板文字,数字 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>
Run Code Online (Sandbox Code Playgroud)
请注意他如何不使用 HTML 模板,而是使用 ecmascript 模板文字来设置 shadowRoot 的 innerHTML。
此后,他使用 querySelector 获取 shadowRoot 的内部元素,并最终将事件侦听器添加到增量和减量按钮。
如果您要使用 HTML 模板,而不是 ecmascript 模板文字,这对您有什么好处?
从概念上讲,我正在努力寻找一种情况,即我更喜欢 HTML 模板元素而不是 Ecmascript 模板文字。
请指教。
模板标签对于 Web 组件本身来说并不是“必需的”。当HTML 导入被推送时,它可能更有意义,允许导入和重用 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>
Run Code Online (Sandbox Code Playgroud)
然后稍后在 JavaScript 中使用它,如下所示:
const template = document.querySelector('#counterTemplate');
const counter = document.cloneNode(template);
shadowRoot.appendChild(counter);
Run Code Online (Sandbox Code Playgroud)
这里的缺点是,它要求模板在实例化之前就存在于 DOM 中,因为它依赖于那里的 #counterTemplate 模板。在某些方面,这使得自定义元素的可移植性较差,因此模板文字可能更可取。我还没有测试两者的性能,但我的直觉告诉我,该模板可能会性能更高。
免责声明:我写了原始博客文章
| 归档时间: |
|
| 查看次数: |
1979 次 |
| 最近记录: |