Skip to main content

JavaScript
Detecting DOM Changes with MutationObserver

script.js

// AZUL CODING ---------------------------------------
// JavaScript - Detecting DOM Changes with MutationObserver
// https://youtu.be/Vn4gqGXACFE


const fruitListNode = document.getElementById("fruit-list");
const addButton = document.getElementById("add-btn");
const removeButton = document.getElementById("remove-btn");
const colourButton = document.getElementById("colour-btn");

const fruits = ["Strawberry", "Banana", "Pear", "Peach", "Mango", "Pineapple"];
const colours = ["red", "green", "blue"];

const observer = new MutationObserver(function(mutations) {
    for (let mutation of mutations) {
        if (mutation.type === "childList") {
            for (let node of mutation.addedNodes) {
                console.log(`A ${node.textContent.toLowerCase()} was added.`);
            }
            for (let node of mutation.removedNodes) {
                console.log(`A ${node.textContent.toLowerCase()} was removed.`);
            }

        } else if (mutation.type === "attributes") {
            console.log(`A ${
                mutation.target.textContent.toLowerCase()
            } was changed from ${mutation.oldValue || "white"} to ${
                mutation.target.className}.`);

        } else if (mutation.type === "characterData") {
            console.log(`A ${
                mutation.oldValue.toLowerCase()
            } was changed to a ${
                mutation.target.textContent.toLowerCase()}.`);

            if (!fruits.includes(mutation.target.textContent)) {
                mutation.target.parentNode.style.fontStyle = "italic";
            } else {
                mutation.target.parentNode.style.fontStyle = "normal";
            }
        }
    }
});

observer.observe(fruitListNode, {
    // Check if a new node has been added or removed
    childList: true,

    // Check if an attribute, e.g. 'class' has changed
    attributes: true,
    attributeFilter: ["class"],
    attributeOldValue: true,

    // Observe subelements as well
    subtree: true,

    // Check if the content of an element has changed
    characterData: true,
    characterDataOldValue: true
});

// To stop the observer...
// observer.disconnect();

// ---

function pickRandom(arr) {
    return arr[Math.floor(Math.random() * arr.length)];
}

addButton.addEventListener("click", function() {
    let randomFruit = pickRandom(fruits);

    const li = document.createElement("li");
    li.textContent = randomFruit;
    li.contentEditable = true;
    fruitListNode.appendChild(li);
});

removeButton.addEventListener("click", function() {
    if (fruitListNode.children.length > 0)
        fruitListNode.removeChild(fruitListNode.lastElementChild);
});

colourButton.addEventListener("click", function() {
    if (fruitListNode.children.length > 0) {
        const randomItem = pickRandom(fruitListNode.children);

        randomItem.className = pickRandom(colours.filter((val) =>
            val !== randomItem.className
        ));
    }
});

Enjoying this tutorial?


index.html

<!-- AZUL CODING --------------------------------------- -->
<!-- JavaScript - Detecting DOM Changes with MutationObserver -->
<!-- https://youtu.be/Vn4gqGXACFE -->


<!DOCTYPE html>
<html>
    <head>
        <title>Azul Coding</title>
        <style>
            body {
                margin: 30px;
                background-color: #03506E;
                color: white;
                font-size: 18px;
            }
            * {
                font-family: 'Inter', sans-serif;
                font-weight: 500;
                font-size: 18px;
            }
            button {
                background-color: white;
                border: none;
                border-radius: 10px;
                padding: 6px 12px;
                cursor: pointer;
            }
            button:active {
                transform: scale(0.9);
            }
            .container {
                display: flex;
                flex-wrap: wrap;
                gap: 10px;
            }
            #fruit-list {
                border: 2px solid #49C8FC;
                border-radius: 10px;
                padding: 10px 30px;
            }
            .red {
                color: #FF9C9C;
            }
            .green {
                color: #95FF95;
            }
            .blue {
                color: #49C8FC;
            }
        </style>
        <script defer src="script.js"></script>
    </head>
    <body>
        <div class="container">
            <button id="add-btn">Add item</button>
            <button id="remove-btn">Remove item</button>
            <button id="colour-btn">Change colour</button>
        </div>
        <ul id="fruit-list"></ul>
    </body>
</html>