即使在定义 observedAttributes 之后也不会调用 attributeChangedCallback
attributeChangedCallback doesn't get called even after defining observedAttributes
在以下代码中,即使创建、更改或删除了 'content' 属性,也永远不会调用 attributeChangedCallback。
class Square extends HTMLElement {
static get observedAttributes() {
return ['content'];
}
constructor(val) {
super();
console.log('inside constructor');
this.attachShadow({mode: 'open'});
this.shadowRoot.appendChild(document.createElement('button'));
this.button = this.shadowRoot.querySelector('button');
this.button.className = "square";
this.content = val;
console.log('constructor ended');
}
get content() {
console.log('inside getter');
return this.button.getAttribute('content');
}
set content(val) {
console.log('setter being executed, val being: ', val);
// pass null to represent empty square
if (val !== null) {
this.button.setAttribute('content', val);
} else {
if (this.button.hasAttribute('content')) {
this.button.removeAttribute('content');
}
}
}
connectedCallback() {
//console.log('connected callback being executed now');
}
// not working :(
attributeChangedCallback(name, oldValue, newValue) {
console.log('attribute changed callback being executed now');
if (name === 'content') {
this.button.innerHTML = newValue?newValue:" ";
}
}
}
customElements.define('square-box', Square);
根据给定的最佳实践 here,我希望属性更改的副作用(在我的例子中是更新 innerHTML)发生在 attributeChangedCallback 中。但是,当我将此更新移至 setter 时,代码工作正常。
set content(val) {
console.log('setter being executed, val being: ', val);
// pass null to represent empty square
if (val !== null) {
this.button.setAttribute('content', val);
} else {
if (this.button.hasAttribute('content')) {
this.button.removeAttribute('content');
}
}
}
你搞混了 parents & children
您正在为元素 (►parent元素)
当你this.button.setAttribute('content', val);
您正在更改 元素(►child 元素)
的 属性
这将永远不会触发(►parent)的attributeChangedCallback
因为它的属性没有改变
您要么必须使用 .getRootNode() and/or .host“提升 DOM”来设置 parent[的属性个元素。
或使用 Custom Events(冒泡 DOM)通知 parents children 有 done/changed 东西
我猜你是故意的
set content(val) {
// loose ==null comparison for null AND undefined,
// element.content=null; will remove the attribute
if (val==null)
this.removeAttribute('content');
else
// but you DO want .content(0) (0==false) set as "0"
this.setAttribute('content', val);
}
在以下代码中,即使创建、更改或删除了 'content' 属性,也永远不会调用 attributeChangedCallback。
class Square extends HTMLElement {
static get observedAttributes() {
return ['content'];
}
constructor(val) {
super();
console.log('inside constructor');
this.attachShadow({mode: 'open'});
this.shadowRoot.appendChild(document.createElement('button'));
this.button = this.shadowRoot.querySelector('button');
this.button.className = "square";
this.content = val;
console.log('constructor ended');
}
get content() {
console.log('inside getter');
return this.button.getAttribute('content');
}
set content(val) {
console.log('setter being executed, val being: ', val);
// pass null to represent empty square
if (val !== null) {
this.button.setAttribute('content', val);
} else {
if (this.button.hasAttribute('content')) {
this.button.removeAttribute('content');
}
}
}
connectedCallback() {
//console.log('connected callback being executed now');
}
// not working :(
attributeChangedCallback(name, oldValue, newValue) {
console.log('attribute changed callback being executed now');
if (name === 'content') {
this.button.innerHTML = newValue?newValue:" ";
}
}
}
customElements.define('square-box', Square);
根据给定的最佳实践 here,我希望属性更改的副作用(在我的例子中是更新 innerHTML)发生在 attributeChangedCallback 中。但是,当我将此更新移至 setter 时,代码工作正常。
set content(val) {
console.log('setter being executed, val being: ', val);
// pass null to represent empty square
if (val !== null) {
this.button.setAttribute('content', val);
} else {
if (this.button.hasAttribute('content')) {
this.button.removeAttribute('content');
}
}
}
你搞混了 parents & children
您正在为元素
当你this.button.setAttribute('content', val);
您正在更改 元素(►child 元素)
的 属性这将永远不会触发(►parent)的attributeChangedCallback
因为它的属性没有改变
您要么必须使用 .getRootNode() and/or .host“提升 DOM”来设置 parent[的属性个元素。
或使用 Custom Events(冒泡 DOM)通知 parents children 有 done/changed 东西
我猜你是故意的
set content(val) {
// loose ==null comparison for null AND undefined,
// element.content=null; will remove the attribute
if (val==null)
this.removeAttribute('content');
else
// but you DO want .content(0) (0==false) set as "0"
this.setAttribute('content', val);
}