/
Custom elements become truly powerful when they can respond to changes in their environment. Lifecycle callbacks are special moments when your custom elements can "wake up" and perform actions - like when they appear on the page or when their attributes change.
Think of lifecycle callbacks as automatic notifications that tell your custom element "Hey, something important just happened!" This allows your elements to stay synchronized with the webpage and respond appropriately to changes.
In this article, you'll learn about the four main lifecycle moments and see simple examples of how to use them effectively in your HTML projects.
Lifecycle callbacks are pre-defined moments in a custom element's existence when the browser automatically runs specific code. These moments include when the element is added to the page, removed from the page, or when its attributes change.
Imagine your custom element as a person going through different life stages - birth, growth, change, and eventually departure. Lifecycle callbacks let you define what happens during each of these important transitions.
The browser handles all the timing automatically. You simply define what should happen at each stage, and the browser takes care of calling your code at the right moment.
The connectedCallback runs when your custom element is first added to the webpage. This is like the element's "birth moment" - the perfect time to set up initial content or prepare the element for use.
The disconnectedCallback runs when your custom element is removed from the webpage. This is the cleanup moment where you can remove any temporary content or reset things.
The attributeChangedCallback runs whenever someone changes an attribute on your custom element. This lets your element react to changes and update accordingly.
The adoptedCallback runs when your element moves to a different HTML document. This is rarely needed but available for special cases.
Here's how lifecycle callbacks work in practice:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lifecycle Callbacks Example</title>
</head>
<body>
<!-- Your custom element will go here -->
<my-greeting name="World"></my-greeting>
<script>
class MyGreeting extends HTMLElement {
// This runs when element is added to page
connectedCallback() {
this.innerHTML = `<p>Hello, ${this.getAttribute('name') || 'Friend'}!</p>`;
}
// This runs when element is removed from page
disconnectedCallback() {
console.log('Goodbye from my-greeting element');
}
}
// Register the custom element
customElements.define('my-greeting', MyGreeting);
</script>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Status Display Example</title>
</head>
<body>
<status-display status="online"></status-display>
<script>
class StatusDisplay extends HTMLElement {
connectedCallback() {
this.updateDisplay();
}
updateDisplay() {
const status = this.getAttribute('status') || 'unknown';
this.innerHTML = `<span>Status: ${status}</span>`;
}
}
customElements.define('status-display', StatusDisplay);
</script>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dynamic Content Example</title>
</head>
<body>
<welcome-message user="Alice"></welcome-message>
<button onclick="changeUser()">Change User</button>
<script>
class WelcomeMessage extends HTMLElement {
connectedCallback() {
this.render();
}
render() {
const user = this.getAttribute('user') || 'Guest';
this.innerHTML = `
<div>
<h3>Welcome, ${user}!</h3>
<p>Thanks for visiting our site.</p>
</div>
`;
}
}
customElements.define('welcome-message', WelcomeMessage);
function changeUser() {
const element = document.querySelector('welcome-message');
element.setAttribute('user', 'Bob');
element.render(); // Manually update for this example
}
</script>
</body>
</html>Use connectedCallback when your element needs to create its initial HTML content based on attributes or other factors.
Use disconnectedCallback when your element needs to clean up things like timers or event listeners to prevent memory leaks.
Use attributeChangedCallback when your element should update its appearance or behavior when attributes change.
Lifecycle callbacks are perfect for elements that need to adapt their content based on their attributes or position in the document.
The browser handles all the timing for you. You don't need to manually detect when elements are added or removed from the page.
Your element's behavior is clearly organized into specific lifecycle moments, making your code easier to understand and maintain.
Elements automatically stay synchronized with their attributes and environment without requiring manual intervention.
Elements only update when necessary, avoiding unnecessary work and keeping your pages fast.
Lifecycle callbacks should perform quick, essential tasks. Avoid heavy computations or long-running operations that might slow down your page.
Always provide fallback values when reading attributes, since users might not always provide them.
Remember to clean up in disconnectedCallback to prevent memory leaks, especially if you create timers or event listeners.
Lifecycle callbacks work in all modern browsers, but older browsers might need polyfills for full custom element support.
Set up your element's initial state and content in connectedCallback rather than in the constructor.
Always provide sensible default values when attributes are missing or empty.
Only update the parts of your element that actually changed, rather than recreating all content.
Choose clear, descriptive names for your custom elements that indicate their purpose.
Lifecycle callbacks are the key to creating responsive, well-behaved custom elements. By understanding when each callback runs and what it's meant for, you can build elements that automatically adapt to changes and provide a smooth user experience.
The four main callbacks - connectedCallback, disconnectedCallback, attributeChangedCallback, and adoptedCallback - cover all the essential moments in your element's life. Start with the basic connected and disconnected callbacks, then add attribute change handling as your elements become more sophisticated.
Remember to keep your callbacks focused and efficient. They should handle the essential setup, updates, and cleanup that make your custom elements reliable and performant. With practice, you'll develop an intuitive sense of which callback to use for different situations, making your web components more powerful and user-friendly.