Web Components 自定义元素生命周期回调函数详解

作者:代码拾荒时间:2026-10-31 07:05:19浏览:428

本文详细解析 Web Components 中自定义元素的生命周期回调函数,包括 connectedCallback、disconnectedCallback、adoptedCallback 和 attributeChangedCallback。通过具体代码示例,展示如何在元素挂载、卸载、移动及属性变更时执行初始化、清理和样式更新操作,帮助开发者灵活控制自定义元素行为。

自定义元素构造函数

在自定义元素的构造函数内,可以定义多个不同的回调函数,这些函数会在元素生命周期的不同阶段被触发。这是 Web Components 规范中的核心机制,使开发者能够更精细地掌控元素的行为逻辑。

  • connectedCallback:当自定义元素首次被插入文档 DOM 树时触发。
  • disconnectedCallback:当自定义元素从文档 DOM 树中移除时触发。
  • adoptedCallback:当自定义元素被移动到新文档时触发。
  • attributeChangedCallback:当自定义元素自身的属性发生增加、删除或修改时触发。

其中,connectedCallback 是在自定义元素首次插入文档 DOM 时调用的。该回调通常用于执行初始化任务,例如绑定事件监听器或发起数据请求。此时元素已存在于文档中,可正常访问 DOM 及其他元素。

disconnectedCallback 是在自定义元素从文档 DOM 中移除时调用的。此回调常用于资源清理工作,如解绑事件监听器或清除定时器。此时元素已脱离文档,无法再访问 DOM 及其他元素。

adoptedCallback 是在自定义元素被移动到新文档时调用的。该回调通常用于处理文档级别的操作,例如重新计算布局(重排)或调整样式。此时元素已从原文档移除并加入新文档。

attributeChangedCallback 是在自定义元素增加、删除或修改自身属性时调用的。此回调用于处理与属性相关的逻辑,例如根据属性值的变化更新元素样式或重新渲染内容。此时属性已更新,可通过新属性值执行相应处理。

需要注意的是,上述回调函数均为可选实现,开发者可根据实际需求选择使用。此外,这些回调函数必须在自定义元素的构造函数中定义,无法在元素实例创建后动态修改。

用法示例

以下通过一个简单示例展示其用法。该示例源自 life-cycle-callbacks 演示(可查看在线示例),主要功能是生成指定大小和颜色的方块。自定义元素的结构如下:

<custom-square l="100" c="red"></custom-square>

此处类的构造函数较为简单,主要将 shadow DOM 附加到元素上,并向 shadow root 中添加一个 <div> 元素和一个 <style> 元素:

var shadow = this.attachShadow({ mode: "open" });
var div = document.createElement("div");
var style = document.createElement("style");
shadow.appendChild(style);
shadow.appendChild(div);

示例中的关键函数是 updateStyle(),它接收一个元素作为参数,获取该元素的 shadow root,定位 <style> 元素,并设置 width、height 以及 background-color 样式。

function updateStyle(elem) {
  var shadow = elem.shadowRoot;
  shadow.querySelector("style").textContent = `
    div {
      width: ${elem.getAttribute("l")}px;
      height: ${elem.getAttribute("l")}px;
      background-color: ${elem.getAttribute("c")};
    }
  `;
}

实际的更新操作在生命周期回调函数中处理,我们在构造函数中注册这些回调。当元素插入 DOM 时,connectedCallback() 函数将执行,其中调用 updateStyle() 函数以确保方块按定义显示;

connectedCallback() {
  console.log('Custom square element added to page.');
  updateStyle(this);
}

disconnectedCallback() 和 adoptedCallback() 回调函数仅向控制台发送消息,提示元素何时从 DOM 移除或移动到其他页面:

disconnectedCallback() {
  console.log('Custom square element removed from page.');
}
adoptedCallback() {
  console.log('Custom square element moved to new page.');
}

每当元素属性发生变化时,attributeChangedCallback() 回调函数会执行。如函数名所示,我们可以获取属性的名称、旧值与新值,从而对属性变化执行单独操作。在当前示例中,我们再次调用 updateStyle() 函数,以确保在属性值变化后方块样式得以更新:

attributeChangedCallback(name, oldValue, newValue) {
  console.log('Custom square element attributes changed.');
  updateStyle(this);
}

需要注意的是,若需在元素属性变化后触发 attributeChangedCallback() 回调函数,必须监听该属性。这可通过定义 observedAttributes() get 函数实现,observedAttributes() 函数体内包含 return 语句,返回需要监听的属性名称数组:

static get observedAttributes() {return ['w', 'l']; }

完整代码

// Create a class for the element
class Square extends HTMLElement {
  // Specify observed attributes so that
  // attributeChangedCallback will work
  static get observedAttributes() {
    return ['c', 'l'];
  }
  constructor() {
    // Always call super first in constructor
    super();
    const shadow = this.attachShadow({mode: 'open'});
    const div = document.createElement('div');
    const style = document.createElement('style');
    shadow.appendChild(style);
    shadow.appendChild(div);
  }
  connectedCallback() {
    console.log('Custom square element added to page.');
    updateStyle(this);
  }
  disconnectedCallback() {
    console.log('Custom square element removed from page.');
  }
  adoptedCallback() {
    console.log('Custom square element moved to new page.');
  }
  attributeChangedCallback(name, oldValue, newValue) {
    console.log('Custom square element attributes changed.');
    updateStyle(this);
  }
}
customElements.define('custom-square', Square);
function updateStyle(elem) {
  const shadow = elem.shadowRoot;
  shadow.querySelector('style').textContent = `
    div {
      width: ${elem.getAttribute('l')}px;
      height: ${elem.getAttribute('l')}px;
      background-color: ${elem.getAttribute('c')};
    }
  `;
}
const add = document.querySelector('.add');
const update = document.querySelector('.update');
const remove = document.querySelector('.remove');
let square;
update.disabled = true;
remove.disabled = true;
function random(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}
add.onclick = function() {
  // Create a custom square element
  square = document.createElement('custom-square');
  square.setAttribute('l', '100');
  square.setAttribute('c', 'red');
  document.body.appendChild(square);
  update.disabled = false;
  remove.disabled = false;
  add.disabled = true;
};
update.onclick = function() {
  // Randomly update square's attributes
  square.setAttribute('l', random(50, 200));
  square.setAttribute('c', `rgb(${random(0, 255)}, ${random(0, 255)}, ${random(0, 255)})`);
};
remove.onclick = function() {
  // Remove the square
  document.body.removeChild(square);
  update.disabled = true;
  remove.disabled = true;
  add.disabled = false;
};

自定义元素的生命周期回调函数是 Web Components 技术中的重要特性,使开发者能够更灵活地控制元素行为。

合理使用这些回调函数,可使自定义元素更易用、易维护,从而提高开发效率和代码质量。

以上就是 Web Components 使用生命周期回调函数实例详解的详细内容,更多关于 Web Components 生命周期函数的资料请关注本站其它相关文章!

作者最新文章