最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Web Components - attributeChangedCallback not firing - Stack Overflow

programmeradmin0浏览0评论

Im just starting out with web ponents and I cant seem to figure out why my attributeChangedCallback isnt firing;

I've been paring it to a ponent ive created where everything is working as it should.

things I've checked:

  1. the spelling of the attr that is changing ("isOpen")
  2. the spelling of attributeChangedCallback (literally copied it from another ponent where it is working just to be sure),
  3. made sure its observedAttributes (plural) and the correct attr is set there,
  4. checked the setter and getter are working fine, and in the toggleStatus function I can log the isOpen attribute, and see it change as expected.

But if i try and do anything inside attributeChangedCallback ( example is just logging name) its not firing.

i am sure I'm missing something really simple??

class HamburgerMenu extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: "open" });
    this.shadowRoot.innerHTML = `
    <svg xmlns="" width="164" height="102" fill="none">
      <g stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="20">
        <path id="top" d="M10 92L154 92"/>
        <path id="middle" d="M10 50.8L154 50.8"/>
        <path id="bottom" d="M10 10L154 10"/>
      </g>
    </svg>`;
    this.svg = this.shadowRoot.querySelector("svg");
    this.svg.addEventListener("click", this.toggleStatus.bind(this));
  }

  static get observedAttributes() {
    return ["isOpen"];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    console.log(name, oldValue, newValue);
  }

  get isOpen() {
    return this.getAttribute("isOpen");
  }

  set isOpen(val) {
    if (val) {
      this.setAttribute("isOpen", val);
    } else {
      this.removeAttribute("isOpen");
    }
  }

  toggleStatus() {
    this.setAttribute("isOpen", String(!eval(this.getAttribute("isOpen"))));
  }
}

if (!window.customElements.get("hamburger-menu")) {
  window.customElements.define("hamburger-menu", HamburgerMenu);
}
<hamburger-menu></hamburger-menu>

Im just starting out with web ponents and I cant seem to figure out why my attributeChangedCallback isnt firing;

I've been paring it to a ponent ive created where everything is working as it should.

things I've checked:

  1. the spelling of the attr that is changing ("isOpen")
  2. the spelling of attributeChangedCallback (literally copied it from another ponent where it is working just to be sure),
  3. made sure its observedAttributes (plural) and the correct attr is set there,
  4. checked the setter and getter are working fine, and in the toggleStatus function I can log the isOpen attribute, and see it change as expected.

But if i try and do anything inside attributeChangedCallback ( example is just logging name) its not firing.

i am sure I'm missing something really simple??

class HamburgerMenu extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: "open" });
    this.shadowRoot.innerHTML = `
    <svg xmlns="http://www.w3/2000/svg" width="164" height="102" fill="none">
      <g stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="20">
        <path id="top" d="M10 92L154 92"/>
        <path id="middle" d="M10 50.8L154 50.8"/>
        <path id="bottom" d="M10 10L154 10"/>
      </g>
    </svg>`;
    this.svg = this.shadowRoot.querySelector("svg");
    this.svg.addEventListener("click", this.toggleStatus.bind(this));
  }

  static get observedAttributes() {
    return ["isOpen"];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    console.log(name, oldValue, newValue);
  }

  get isOpen() {
    return this.getAttribute("isOpen");
  }

  set isOpen(val) {
    if (val) {
      this.setAttribute("isOpen", val);
    } else {
      this.removeAttribute("isOpen");
    }
  }

  toggleStatus() {
    this.setAttribute("isOpen", String(!eval(this.getAttribute("isOpen"))));
  }
}

if (!window.customElements.get("hamburger-menu")) {
  window.customElements.define("hamburger-menu", HamburgerMenu);
}
<hamburger-menu></hamburger-menu>

Share Improve this question edited Nov 25, 2023 at 9:54 Danny '365CSI' Engelman 21.4k2 gold badges46 silver badges63 bronze badges asked Mar 6, 2020 at 14:37 Phl3basPhl3bas 431 silver badge6 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 7
  • Attributes must be lowercase, change "isOpen" to "isopen" and it will work
    see SO answer: are html5 data attributes case insensitive?

  • Your use of eval is creative; but there is a toggleAttribute method:
    see: https://developer.mozilla/en-US/docs/Web/API/Element/toggleAttribute

  • Your code runs because you only interact with the shadowRoot in the constructor.
    For other DOM related code you may have to wait till the connectedCallback (now not in your code) runs.
    For lifecycle see: https://andyogo.github.io/custom-element-reactions-diagram/

发布评论

评论列表(0)

  1. 暂无评论