当 dom 中不再存在元素时,SetInterval 将 运行 保留在 webcomponent 中
SetInterval keeps running in webcomponent when element is not present in dom anymore
目前,我正在开发一个协调多个 Web 组件的简单应用程序。其中一个组件包含一个 setInterval 函数。该函数保留 运行,即使组件本身不再出现在 dom 中。谁能给我解释一下为什么会这样?
这是一个简单的复制:
const selectorEl = document.getElementsByTagName('body')[0];
selectorEl.innerHTML = '<my-component></my-component>'; // Append custom component to body
class WebComponent extends HTMLElement {
constructor() {
super();
this.innerHTML = '<span>This should not be visible since I am removed instantly!</span>';
setInterval(() => console.log('I am still running...'), 2000);
}
}
window.customElements.define('my-component', WebComponent);
selectorEl.innerHTML = ''; // Remove element from the dom directly
您需要使用 disconnectedCallback 挂钩,一旦组件从 dom 中移除,它就会被调用,因此在此函数中,您可以清除间隔。
disconnectedCallback() {
clearInterval(interval)
}
您需要使用lifecycle callbacks才能正确使用setInterval
和clearInterval
。
示例如下:
const selectorEl = document.getElementsByTagName("body")[0];
selectorEl.innerHTML = "<my-component></my-component>"; // Append custom component to body
class WebComponent extends HTMLElement {
connectedCallback() {
this.innerHTML =
"<span>This should not be visible since I am removed instantly!</span>";
this.interval = setInterval(
() => console.log("I am still running...", Math.random()),
2000
);
}
disconnectedCallback() {
clearInterval(this.interval);
}
}
window.customElements.define("my-component", WebComponent);
setTimeout(() => selectorEl.innerHTML = "",7000); // Remove element from the dom directly
Web 组件有自己的生命周期,当一个元素从 DOM 中删除时,disconnectedCallback()
将被调用。当元素从 DOM 中移除时,会调用生命周期钩子。因此,它是添加清理逻辑和释放资源的理想场所。在您的情况下,请调用 clearInterval
方法,该方法会像您所做的那样清除使用 setInterval() 方法设置的计时器。
disconnectedCallback() {
clearInterval(interval)
}
一个更简洁的例子:
<script>
customElements.define("my-component", class extends HTMLElement {
connectedCallback() {
console.log("connectedCallback" , this.isConnected);
this.innerHTML = "A Web Component";
setTimeout(() => this.remove(), 2000); // triggers disconnectedCallback
this.interval = setInterval(() => this.innerHTML += ".", 50);
}
disconnectedCallback() {
console.log("disconnectedCallback" , this.isConnected);
clearInterval(this.interval);
}
});
</script>
<my-component></my-component>
备注
DOM 元素不再存在于 disconnectedCallback
中,但 Web 组件仍存在于内存中,因此您可以访问之前创建(或附加)的任何内容
Drag/drop 或 append
操作触发 disconnectedVCallback
然后 再次触发 connectedCallback
目前,我正在开发一个协调多个 Web 组件的简单应用程序。其中一个组件包含一个 setInterval 函数。该函数保留 运行,即使组件本身不再出现在 dom 中。谁能给我解释一下为什么会这样?
这是一个简单的复制:
const selectorEl = document.getElementsByTagName('body')[0];
selectorEl.innerHTML = '<my-component></my-component>'; // Append custom component to body
class WebComponent extends HTMLElement {
constructor() {
super();
this.innerHTML = '<span>This should not be visible since I am removed instantly!</span>';
setInterval(() => console.log('I am still running...'), 2000);
}
}
window.customElements.define('my-component', WebComponent);
selectorEl.innerHTML = ''; // Remove element from the dom directly
您需要使用 disconnectedCallback 挂钩,一旦组件从 dom 中移除,它就会被调用,因此在此函数中,您可以清除间隔。
disconnectedCallback() {
clearInterval(interval)
}
您需要使用lifecycle callbacks才能正确使用setInterval
和clearInterval
。
示例如下:
const selectorEl = document.getElementsByTagName("body")[0];
selectorEl.innerHTML = "<my-component></my-component>"; // Append custom component to body
class WebComponent extends HTMLElement {
connectedCallback() {
this.innerHTML =
"<span>This should not be visible since I am removed instantly!</span>";
this.interval = setInterval(
() => console.log("I am still running...", Math.random()),
2000
);
}
disconnectedCallback() {
clearInterval(this.interval);
}
}
window.customElements.define("my-component", WebComponent);
setTimeout(() => selectorEl.innerHTML = "",7000); // Remove element from the dom directly
Web 组件有自己的生命周期,当一个元素从 DOM 中删除时,disconnectedCallback()
将被调用。当元素从 DOM 中移除时,会调用生命周期钩子。因此,它是添加清理逻辑和释放资源的理想场所。在您的情况下,请调用 clearInterval
方法,该方法会像您所做的那样清除使用 setInterval() 方法设置的计时器。
disconnectedCallback() {
clearInterval(interval)
}
一个更简洁的例子:
<script>
customElements.define("my-component", class extends HTMLElement {
connectedCallback() {
console.log("connectedCallback" , this.isConnected);
this.innerHTML = "A Web Component";
setTimeout(() => this.remove(), 2000); // triggers disconnectedCallback
this.interval = setInterval(() => this.innerHTML += ".", 50);
}
disconnectedCallback() {
console.log("disconnectedCallback" , this.isConnected);
clearInterval(this.interval);
}
});
</script>
<my-component></my-component>
备注
DOM 元素不再存在于
disconnectedCallback
中,但 Web 组件仍存在于内存中,因此您可以访问之前创建(或附加)的任何内容Drag/drop 或
append
操作触发disconnectedVCallback
然后 再次触发connectedCallback