在这个项目中,我正在尝试创建一个自定义组件,该组件将充当地图。我仍在通过 W3C 文档和几个 Youtube 视频学习 Web 组件的基础知识。
主要问题是,在组件类中有一个调用的函数attributeChangedCallback()
,每当其中一个属性更改时都会触发,这些属性包含在observedAttributes()
函数中,并且在设置它们之后(前面提到的函数)我尝试访问shadow DOM(即声明connectedCallback()
将在组件加载到 HTML body 元素中后触发)通过选择器。但是,如果我这样做,变量内容为空。
attributeChangedCallback()
应该在加载内容之后加载,所以我不明白为什么会发生这种情况,每次属性更改时我都需要访问这个元素,以便我可以更新它的内容。奇怪的事实:如果我每次attributeChangedCallback()
执行它都会记录两次(因为我有两个属性被监视)。
这是片段:
class GeoComponent extends HTMLElement {
constructor() {
super();
this.shadow = this.createShadowRoot();
this._latitude = 0;
this._longitude = 0;
}
get latitude(){
return this._latitude;
}
get longitude(){
return this._longitude;
}
set latitude(val){
this.setAttribute('latitude', val);
}
set longitude(val){
this.setAttribute('longitude', val);
}
static get observedAttributes(){
return ['latitude', 'longitude'];
}
attributeChangedCallback(name, oldVal, newVal){
let geoComp = this.shadow.getElementById('geo');
console.log(geoComp);
switch(name){
case 'latitude':
this._latitude = parseInt(newVal, 0) || 0;
// geoComp.innerHTML = `${this.latitude}, ${this.longitude}`;
break;
case 'longitude':
this._longitude = parseInt(newVal, 0) || 0;
// geoComp.innerHTML = `${this.latitude}, ${this.longitude}`;
break
}
}
connectedCallback(){
let template = `
<div class="geo-component" id="geo">
</div>
`;
this.shadow.innerHTML = template;
}
}
window.customElements.define('geo-component', GeoComponent);
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="geoComponent.js"></script>
</head>
<body>
<h1>Geo-Component</h1>
<geo-component latitude="12" longitude="-70"></geo-component>
</body>
</html>
更新
就像@acdcjunior 在更改this.createShadowRoot();
为this.shadow = this.attachShadow({mode: 'open'});
(从ShadowDOM v0 到v1)之后提到的那样解决了我的问题,因为该connectedCallback()
函数在幕后执行并且只执行一次。