我创建了一个非常基本的自定义元素,它可以根据提供的属性 person
更改其值。但是每当我加载我的自定义元素时,我都会收到此错误:Cannot set property 'innerHTML' of null
。当我向 attributeChangedCallback 函数添加断点时,我确实可以看到加载时元素不存在。当我继续加载时,虽然元素加载完美。
我可以想象,因为我使用 webpack 来捆绑我所有的文件,所以问题来自于在主体末尾加载元素,而不是在我的头脑中加载元素。
我的元素.js:
class MyElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({mode: 'open'});
this._person = '';
}
get person() {
return this._name;
}
set person(val) {
this.setAttribute('person', val);
}
static get observedAttributes() {
return ['person'];
}
attributeChangedCallback(attrName, oldVal, newVal) {
let myElementInner = this.shadow.querySelector('.my-element-inner');
switch (attrName) {
case 'person':
this._person = newVal;
// ======================
// The error occures here
// ======================
myElementInner.innerHTML = `My name is ${this._person}`;
}
}
connectedCallback() {
var template =
`
<style>
.my-element-inner {
outline: blue dashed 1px;
background-color: rgba(0,0,255,.1);
}
</style>
<span class="my-element-inner">My name is ${this._person}</span>
`
this.shadow.innerHTML = template;
}
}
customElements.define('my-element', MyElement);
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebPack Test Page</title>
</head>
<body>
<my-element person="André"></my-element>
<!-- Here goes the bundle.js -->
</body>
</html>
最佳答案
attributeChangedCallback()
可以在 connectedCallback
之前或之后调用,具体取决于自定义元素的使用方式。
如果将 connectedCallback
逻辑移动到构造函数中,一切都会好起来的
另一种选择是检查 myElementInner
是否为 null
并将您的代码保留在 connectedCallback
class MyElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({mode: 'open'});
this._person = '';
var template =
`
<style>
.my-element-inner {
outline: blue dashed 1px;
background-color: rgba(0,0,255,.1);
}
</style>
<span class="my-element-inner">My name is ${this._person}</span>
`
this.shadow.innerHTML = template;
}
get person() {
return this._person;
}
set person(val) {
this.setAttribute('person', val);
}
static get observedAttributes() {
return ['person'];
}
attributeChangedCallback(attrName, oldVal, newVal) {
let myElementInner = this.shadow.querySelector('.my-element-inner');
switch (attrName) {
case 'person':
this._person = newVal;
if (myElementInner) {
myElementInner.innerHTML = `My name is ${this._person}`;
}
}
}
}
customElements.define('my-element', MyElement);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebPack Test Page</title>
</head>
<body>
<my-element person="André"></my-element>
<!-- Here goes the bundle.js -->
</body>
</html>
关于javascript - Web 组件 "Cannot set property ' innerHTML' of null",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51987772/