Javascript 为什么要调用attributeChangedCallback两次?

Javascript 为什么要调用attributeChangedCallback两次?,javascript,html,web-component,custom-element,Javascript,Html,Web Component,Custom Element,我正在构建一个简单的自定义元素,使用。我已经注册了一个要“监视”的属性(使用observedAttributes()),当我更改此属性的值时,函数attributeChangedCallback会被调用两次 以下是HTML代码: <my-component id="compo" foo="bar"></my-component> <button id="myBtn">Change attribute

我正在构建一个简单的自定义元素,使用。我已经注册了一个要“监视”的属性(使用
observedAttributes()
),当我更改此属性的值时,函数
attributeChangedCallback
会被调用两次

以下是HTML代码:

<my-component id="compo" foo="bar"></my-component>

<button id="myBtn">Change attribute value</button>
在该页面上,当我单击按钮时,
控制台中有以下日志。log

[my component]属性foo从bar更改为baz

[my component]属性foo从bar更改为baz

为什么调用了两次
attributeChangedCallback
?我怎样才能避免呢

本例的JSFIDLE如下所示:


谢谢。

我查看了您的JSFIDLE,它实际上不会在单击按钮时调用两次,而是在呈现
时首先调用,因为您正在设置
foo
的值;第二,当你点击按钮时

您还可以使用开发工具在JSFIDLE上调试它,然后按Ctrl+Shift+F查找并调试该函数


由于
custom elements.js
polyfill是alpha版本,还不稳定,因此您应该使用:

  • v1.3

我得到了两个更改,但是在您的JSFIDLE示例中是从null->bar,然后是baz->baz。事实上,但是-正如我在对@ikram shah answer的评论中所解释的,问题似乎出在polyfill上。Chrome v54+正在以本机方式实现
customElements
,因此不使用polyfill,该函数只调用一次。谢谢。我已经在最新版本的Chrome上测试了我的JSFIDLE,实际上这个调用只进行了一次。在我的专业电脑上,我使用的是Chrome v53,它没有实现customElements(在v54中添加),因此使用了polyfill,在那里,调用两次。所以问题出在polyfill上!
class MyComponent extends HTMLElement {
  constructor() {
    super();
  }
  
  static get observedAttributes() {
    return ['foo'];
  }
  
  attributeChangedCallback(attrName, oldVal, newVal) {
    console.log('[my component] attribute', attrName, 'changed from', oldVal, 'to', newVal);
  }
}

window.customElements.define('my-component', MyComponent);

// Change value of the component attribute
$('#myBtn').click(() => $('#compo').attr('foo', 'baz'));