I have implemented the following code for observing changes in class:
$(document).ready(function () {
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === "class") {
var attributeValue = $(mutation.target).prop(mutation.attributeName);
console.log("Class attribute changed to:", attributeValue);
}
});
});
observer.observe(document.querySelector(".xxx"), {
attributes: true
}); });
JSFiddle link: https://jsfiddle.net/8Lfj0ev3/
Ideally, I want this to listen for changes in all elements with class 'xxx'. But it is only listening to first element with xxx class and ignoring others. How can I fix this?
Two ways to address this:
observe callsYou can call observe multiple times to watch multiple elements:
$(".xxx").each(function() {
observer.observe(this, {
attributes: true
});
});
Live Example:
$(document).ready(function() {
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === "class") {
var attributeValue = $(mutation.target).prop(mutation.attributeName);
console.log("Class attribute changed to:", attributeValue);
}
});
});
$(".xxx").each(function() {
observer.observe(this, {
attributes: true
});
});
});
setTimeout(function() {
$(".d1").addClass("x1");
}, 800);
setTimeout(function() {
$(".d2").addClass("x2");
}, 1600);
setTimeout(function() {
$(".d3").addClass("x3");
}, 2400);
<div class="d1 xxx"></div>
<div class="d2 xxx"> </div>
<div class="d3 xxx"> </div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
But another option is to watch the subtree of the nearest container they're all in and then only pay attention to changes if they occurred within a .xxx element:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === "class") {
var $target = $(mutation.target); // ***
if ($target.hasClass("xxx")) { // ***
var attributeValue = $target.prop(mutation.attributeName);
console.log("Class attribute changed to:", attributeValue);
}
}
});
});
observer.observe(document.body, { // ***
attributes: true,
subtree: true // ***
});
Live Example:
$(document).ready(function() {
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === "class") {
var $target = $(mutation.target);
if ($target.hasClass("xxx")) {
var attributeValue = $target.prop(mutation.attributeName);
console.log("Class attribute changed to:", attributeValue);
}
}
});
});
observer.observe(document.body, {
attributes: true,
subtree: true
});
});
setTimeout(function() {
$(".d1").addClass("x1");
}, 800);
setTimeout(function() {
$(".d2").addClass("x2");
}, 1600);
setTimeout(function() {
$(".d3").addClass("x3");
}, 2400);
<div class="d1 xxx"></div>
<div class="d2 xxx"> </div>
<div class="d3 xxx"> </div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
In that example the nearest container is document.body, but of course in your real situation there may be something closer to the elements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With