1

I want write JavaScript code which should listen to change class name of element from DOM and execute function as below...

function(){
  console.log("Catch class name change!");
}

I have button...

<button class="btn-large red" data-bind="text: submitLabel, trueClick: submit,
          css: { 'light-skin': ff.DealTicket.useLightSkin, disabled: !isValid() || isOrderPending() ||isSubmitting(), blue: isBuy(), red: !isBuy(), yellow: isOCO() }">Place Sell Trade</button>

...which changes own class name from

<button class="btn-large red">...

to

<button class="btn-large red dissabled">...

I get this button by

document.querySelector('btn-large.red');

How can I listen to change this name class value ?

I try using eventListener and DOMCOntentLoad, DOMSubtreeModified and it not works.

document.querySelector("btn-large.red").addEventListener("DOMContentLoaded", function(){
        console.log("Catch class name change!");
    });
CeZet
  • 1,473
  • 5
  • 22
  • 44

1 Answers1

3

You can use a mutation observer to listen to changes to the element's attributes; when a class is added/removed, the class attribute is updated.

Example:

// The function to call when the class changes
function classChanged(b) {
  console.log("The class changed: " + b.className);
}

// The button
var btn = document.getElementById("the-button");
console.log("Initial class: " + btn.className);

// The mutation observer
var ob = new MutationObserver(function() {
   classChanged(btn);
});
ob.observe(btn, {
  attributes: true,
  attributeFilter: ["class"]
});

// Just for our example, something to periodically modify
// the classes on the button
var timer = setInterval(function() {
  btn.classList.toggle("fuzz");
  btn.classList.toggle("bizz");
}, 500);
setTimeout(function() {
  console.log("Done");
  clearInterval(timer);
}, 10000);
.foo {
  color: blue;
}
.bar {
  color: green;
}
<button id="the-button" class="foo fuzz">This is the button</button>
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I have problem that it spam console which thousands of records. Are You sure that checked only changes of class name in this button ? Please look at button which I paste, made example base on this button. – CeZet Nov 15 '16 at 11:12
  • Maybe we should check only when the class name `dissabled` was added to class name ? – CeZet Nov 15 '16 at 11:18
  • @czArek: If you're getting thousands of callbacks, then apparently the attribute is being updated thousands of times, which might be something to check on. But you can readily rate-limit the number of calls, just check for specific values, etc. Having thousands of calls to your observer callback isn't a problem, if you then just check for `disabled.` in the class list. – T.J. Crowder Nov 15 '16 at 12:18
  • So can we check only when appear "disabled" in class name ? Check only this name ? When changes from "btn-large" to "btn-large disabled" ? How I must filter the `ob.observe(button, { attributes: true, attributeFilter: ["class"] });` – CeZet Nov 15 '16 at 12:26
  • @czArek: The observer can't do that filtering for you. An `if` statement in the observer's callback is all you need: `if (btn.classList.contains("disabled"))` – T.J. Crowder Nov 15 '16 at 12:35
  • Can You edit your Code snippet and put IF statement ? – CeZet Nov 15 '16 at 12:38
  • 1
    I add it to function which is running when catch the change. Thanks T.J. ! – CeZet Nov 15 '16 at 12:53