Есть ли способ наблюдать мутацию 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>
Вы захотите настроить параметры, которые вы передаете наблюдателю, и код в обратном вызове наблюдателя, чтобы, конечно, соответствовать вашему сценарию. : -)