【问题标题】:attributeChangedCallback doesn't get called even after defining observedAttributes即使在定义observedAttributes 之后也不会调用attributeChangedCallback
【发布时间】:2020-06-04 17:58:31
【问题描述】:

在以下代码中,attributeChangedCallback 永远不会被调用,即使 'content' 属性被创建、更改或删除。

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 中。但是,当我将此更新移动到设置器时,代码可以正常工作。

【问题讨论】:

    标签: javascript html web-component custom-element


    【解决方案1】:
    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');
                }
            }
    
        }
    

    你把父母和孩子搞混了

    您正在元素 (►parent 元素)上定义 setter

    当你做this.button.setAttribute('content', val);

    您正在更改 元素(►child 元素)的 属性

    这将永远不会触发(►parent)
    attributeChangedCallback 因为它的属性没有改变

    您要么必须使用 .getRootNode() 和/或 .host “向上 DOM” 设置 parent 元素的属性

    或使用Custom Events(冒泡DOM)通知父母孩子们已经完成/改变了一些事情

    我猜你是故意的

    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);
        }
    

    【讨论】:

      猜你喜欢
      • 2013-06-18
      • 2020-06-23
      • 1970-01-01
      • 2017-03-23
      • 1970-01-01
      • 2018-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多