乐趣区

关于前端:Web-Components-中使用生命周期回调函数

在 custom element 的构造函数中,能够指定多个不同的回调函数,它们将会在元素的不同生命期间被调用。这是 Web Components 技术中的一个重要个性,它可能让开发者更加灵便地管制元素的行为

  • connectedCallback:当 custom element 首次被插入文档 DOM 时,被调用。
  • disconnectedCallback:当 custom element 从文档 DOM 中删除时,被调用。
  • adoptedCallback:当 custom element 被挪动到新的文档时,被调用。
  • attributeChangedCallback: 当 custom element 减少、删除、批改本身属性时,被调用。

其中,connectedCallback 是在 custom element 首次被插入文档 DOM 时被调用的。这个回调函数通常用于执行一些初始化操作,比方增加事件监听器、申请数据等等。在这个时候,元素曾经被增加到了文档中,能够拜访到 DOM 和其余元素。

disconnectedCallback 是在 custom element 从文档 DOM 中删除时被调用的。这个回调函数通常用于清理一些资源,比方勾销事件监听器、进行定时器等等。在这个时候,元素曾经不再被文档所蕴含,无法访问到 DOM 和其余元素。

adoptedCallback 是在 custom element 被挪动到新的文档时被调用的。这个回调函数通常用于解决一些文档级别的操作,比方从新计算布局(重排)、批改款式等等。在这个时候,元素曾经从原来的文档中移除,并被增加到了新的文档中。

attributeChangedCallback 是在 custom element 减少、删除、批改本身属性时被调用的。这个回调函数通常用于解决一些属性相干的逻辑,比方依据属性值的变动更新元素的款式、从新渲染元素等等。在这个时候,元素的属性曾经被批改,能够通过新的属性值来进行相应的解决。

须要留神的是,这些回调函数都是可选的,开发者能够依据理论需要来抉择应用哪些回调函数。另外,这些回调函数只能在 custom element 的构造函数中进行定义,不能在元素实例中进行批改。

用法示例

咱们来看一下它们的一下用法示例。上面的代码出自 life-cycle-callbacks 示例(查看在线示例)。这个简略示例只是生成特定大小、色彩的方块。custom element 看起来像上面这样:

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

这里,类的构造函数很简略 — 咱们将 shadow DOM 附加到元素上,而后将一个 <div> 元素和 <style> 元素附加到 shadow root 上:

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> 元素,并增加 widthheight 以及 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;
};

Custom element 的生命周期回调函数是 Web Components 技术中的一个重要个性,它可能让开发者更加灵便地管制元素的行为。通过正当地应用这些回调函数,能够让自定义元素更加易用、易保护,进步开发效率和代码品质。

退出移动版