自定义元素需在observedattributes中声明属性名才能监听其变化,attributechangedcallback接收name、oldvalue、newvalue参数,初始html属性值会在升级后触发回调,移除属性时newvalue为null。

自定义元素可以通过定义 attributeChangedCallback 钩子函数来监听指定属性的变化,但前提是必须在 observedAttributes 静态 getter 中明确列出要监听的属性名。
必须声明要监听的属性
浏览器不会自动监听所有属性,只有出现在 observedAttributes 数组里的属性变更才会触发 attributeChangedCallback。属性名区分大小写,且必须是字符串形式。
- 只支持监听 HTML 属性(即通过
setAttribute、el.attr = val或 HTML 标签中直接写的属性) - 不监听 JavaScript 属性(如
el.myProp = value),除非你手动同步到对应 attribute - 若属性初始值在 HTML 中声明(如
<my-el data-id="123"></my-el>),首次初始化时也会触发该回调
正确实现 attributeChangedCallback
该方法接收三个参数:name(变更的属性名)、oldValue(旧值)、newValue(新值)。注意:当属性被移除时,newValue 为 null,oldValue 是移除前的值。
- 避免在回调中直接调用
setAttribute同一属性,否则可能引发无限循环 - 建议先判断
oldValue !== newValue再执行逻辑,因为有时会收到 undefined → null 等非实质变化 - 若需响应布尔属性(如
disabled),注意其存在即为 true,移除即为 false,newValue在存在时是空字符串或属性名本身(取决于是否显式赋值)
常见写法示例
以下是一个监听 count 和 active 属性的自定义元素:
class MyCounter extends HTMLElement {
static get observedAttributes() {
return ['count', 'active'];
}
<p>attributeChangedCallback(name, oldValue, newValue) {
if (name === 'count') {
this._count = Number(newValue) || 0;
this.render();
} else if (name === 'active') {
this._isActive = newValue !== null;
this.toggleStyle();
}
}</p><p>render() { /<em> 更新 DOM </em>/ }
toggleStyle() { /<em> 切换 class </em>/ }
}</p>注意生命周期时机
attributeChangedCallback 在元素实例化后、且属性实际变更时同步调用。但它**不会**在 connectedCallback 之前触发初始属性(即使 HTML 中已写好),而是会在元素升级完成后的下一个微任务中触发——也就是说,初始属性值一定会触发一次该回调。
- 如果需要确保 DOM 已就绪再响应属性,可结合
connectedCallback做延迟处理,或在回调里检查this.isConnected - 动态创建元素后设置属性(如
el.setAttribute('count', '5'))会立即触发回调 - 使用
removeAttribute也会触发,此时newValue为null











