Есть ли способ наблюдать DOM-мутацию элемента с помощью селектора CSS, и если да, то как это сделать? - PullRequest
0 голосов
/ 21 февраля 2020

Существует определенный веб-сайт с определенным элементом HTML, который, если я правильно понимаю, имеет один и тот же класс для события DOMContentLoaded и события load, но когда-то после события load этот класс ( и, возможно, также будут изменены идентификатор и атрибуты HTML).

Я бы хотел "наблюдать" за этим элементом с первого момента его появления в DOM, поэтому для автоматического отслеживания любого изменения его HTML может have.

Есть ли способ наблюдать DOM-мутацию элемента с помощью селектора CSS и, если да, как это сделать?

Я спрашиваю это, предполагая, что я понял "наблюдение "концепция в JavaScript правильно.

1 Ответ

1 голос
/ 21 февраля 2020

Есть ли способ наблюдать мутацию DOM элемента с помощью селектора CSS ...

В некотором роде. Вы можете наблюдать все модификации в элементе и его потомках с помощью наблюдателя мутации , и вы можете использовать метод matches для добавленных элементов или изменены, чтобы увидеть, соответствуют ли они данному CSS селектору (или использовать querySelector в контейнере, который вы смотрите).

С комбинацией наблюдателя мутации и matches / querySelector(All), Вы можете увидеть любые изменения, которые вам нужны.

// Get the container
let container = document.getElementById("container");

// The selector we're interested in
let selector = "div.foo";

// Set up a mutation observer
let observer = new MutationObserver(records => {
    // A mutation occurred within the container.
    // `records` contains the information about the mutation(s)

    // If you're looking to see if a new element matching the selector
    // was *added*, you can loop through the added nodes (if any)
    for (const record of records) {
        for (const added of record.addedNodes) {
            if (added.nodeType === Node.ELEMENT_NODE && added.matches(selector)) {
                console.log("Matching element added: " + added.textContent);
            }
        }
    }

    // If you're looking to see if an element *changed* to match the
    // selector, you can look at the target of each record
    for (const {target} of records) {
        if (target.nodeType === Node.ELEMENT_NODE && target.matches(selector)) {
            console.log("Element changed to match: " + target.textContent);
        }
    }

    // Or alternatively ignore the records and *why* an element now matches,
    // and just see if any does.
    const found = container.querySelectorAll(selector);
    if (found.length) {
        console.log("Matching elements found: " + found.length);
        for (const {textContent} of found) {
            console.log("Matching element found: " + textContent);
        }
    }
});
observer.observe(container, {
    // Tweak what you're looking for depending on what change you want to find.
    childList: true,
    subtree: true,
    attributes: true
});

// Add five div elements; the fourth will have the
// class we're interested in.
let counter = 0;
let timer = setInterval(() => {
    const div = document.createElement("div");
    ++counter;
    div.textContent = "Div #" + counter;
    if (counter === 4) {
        div.className = "foo";
    }
    console.log("Adding div: " + div.textContent);
    container.appendChild(div);
    if (counter === 5) {
        clearInterval(timer);
    }
}, 200);

// After 1200ms, *change* one of the divs to match the selector
setTimeout(() => {
    const div = container.querySelector("div:not(.foo)");
    console.log("Changing element to match: " + div.textContent);
    div.className = "foo";
}, 1200);
<div id="container">
    This is the container.
</div>

Вы захотите настроить параметры, которые вы передаете наблюдателю, и код в обратном вызове наблюдателя, чтобы, конечно, соответствовать вашему сценарию. : -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...