Tac*_*ack 4 html javascript web-component custom-element native-web-component
我正在制作一个 Web 组件,它将显示“Hello {name}!” 从哪里来。{name} name="foo"当我尝试它时,我没有收到任何错误,但它只显示“Hello null!”。
索引.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js"></script>
</head>
<body>
<hello-world name="Joe"></hello-world>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
脚本.js:
class HelloWorld extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
const p = document.createElement('p');
p.innerHTML = `Hello ${this.getAttribute('name')}!`;
this.shadowRoot.append(p);
}
}
customElements.define('hello-world', HelloWorld);
Run Code Online (Sandbox Code Playgroud)
在任何情况下,我们假设name总是有一个输入。
您不能读取 中的属性 constructor ,否则就违反了规范:
不得检查元素的属性和子元素,因为在非升级情况下不会出现任何属性和子元素,并且依赖升级会降低元素的可用性。
从:https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-conformance
您必须延迟此类工作,直到connectedCallback触发器触发,或者在属性的情况下,配置适当的attributeChangedCallback.
符合规范还将解决您最初的问题,并且将大大增强 Web 组件的功能和实用性。
请注意,选择 HTML 规范中已存在的属性名称作为通用属性也不是最聪明的想法。
class HelloWorld extends HTMLElement {
p = document.createElement('p');
constructor() {
super();
this.attachShadow({ mode: 'open' }).append(this.p);
}
static get observedAttributes() { return ['greeting-name']; }
attributeChangedCallback(attr, oldVal, newVal) {
if (oldVal === newVal) return; // nothing to do
switch (attr) {
case 'greeting-name':
this.p.textContent = `Hello ${newVal || 'world'}!`;
break;
}
}
connectedCallback() {
if (!this.getAttribute('greeting-name')) { this.setAttribute('greeting-name', 'world'); }
}
}
customElements.define('hello-world', HelloWorld);Run Code Online (Sandbox Code Playgroud)
<hello-world greeting-name="Joe"></hello-world>
<hello-world id="foo"></hello-world>
<input type="text" oninput="document.getElementById('foo').setAttribute('greeting-name', this.value)" placeholder="Type a name" />Run Code Online (Sandbox Code Playgroud)