Web Components family - life cycle of custom components

Posted by lucifersolutions on Sun, 13 Feb 2022 16:05:10 +0100

preface

What is the "life cycle"? As the name suggests, the life cycle refers to the whole process of an object from before its birth to after its demise. Of course, the specific stages of the life cycle of different objects may be different.

When we use the front-end component framework, we all know that each component has its own life cycle. After clarifying the component life cycle, developers can execute different code logic in different life cycles of components, so as to achieve the role of managing components.

In order to make the use of Custom Elements more flexible, it also has a "life cycle" callback function, which allows developers to define the methods that can be executed in different life periods of components.

Custom Elements lifecycle Division

In the constructor of Custom Elements, you can specify multiple different callback functions, which will be called at different life times of the element:

  • connectedCallback: called when Custom Elements are first inserted into the document DOM.
  • disconnectedCallback: called when Custom Elements are deleted from the document DOM.
  • adoptedCallback: called when Custom Elements are moved to a new document.
  • attributeChangedCallback: called when Custom Elements add, delete or modify their own attributes.

Note: the lifecycle callback function of the custom element is used in its constructor.

Use of lifecycle callback functions

Let's first look at the effect:

It should be noted here that the adptedcallback callback is triggered only when the custom element is moved to a new document (generally iframe).

The code is as follows:

<!--index.html-->
<head>
    <style>
        body {
            padding: 50px;
        }

        custom-square {
            margin: 15px;
        }

        iframe {
            width: 100%;
            height: 250px;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <h1>Custom Elements life cycle</h1>
    <div>
        <button class="add">Add Square reach DOM</button>
        <button class="update">change Square Properties of</button>
        <button class="remove">remove Square element</button>
        <button class="move">move Square reach Iframe</button>
    </div>
    <iframe src="./other.html"></iframe>
    <script src="./square.js"></script>
    <script src="./index.js"></script>
</body>

<!--other.html-->
<body>
    <h1>This is other.html</h1>
</body>
// square.js
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")};
      }
    `;
}

class Square extends HTMLElement {
    static get observedAttributes() {
        return ["c", "l"];
    }

    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 Be mounted to the page");
        updateStyle(this);
    }

    disconnectedCallback() {
        console.log("custom-square Removed from page");
    }

    adoptedCallback() {
        console.log("custom-square Moved to new page");
    }

    attributeChangedCallback(name, oldValue, newValue) {
        console.log("custom-square Attribute value changed");
        updateStyle(this);
    }
}

customElements.define("custom-square", Square);
// index.js
const add = document.querySelector(".add");
const update = document.querySelector(".update");
const remove = document.querySelector(".remove");
const move = document.querySelector(".move");
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;
};

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)})`);
};

move.onclick = function () {
    window.frames[0].document.body.appendChild(square);
}

Concluding remarks

The above is a simple use example of the Custom Elements lifecycle callback function. I hope it can be helpful to you!

In the callback function of Custom Elements, there are few usage scenarios of adoptedCallback, which needs attention.

~

~End of this article, thank you for reading!

~

Learn interesting knowledge, make interesting friends and shape interesting souls!

Hello, I'm Programming samadhi Hermit Wang, my official account is " Programming samadhi "Welcome to pay attention and hope you can give us more advice!