Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: Listen for attribute change?

Is it possible in JavaScript to listen for a change of attribute value? For example:

var element=document.querySelector('…');
element.addEventListener( ? ,doit,false);

element.setAttribute('something','whatever');

function doit() {

}

I would like to respond to any change in the something attribute.

I have read up on the MutationObserver object, as well as alternatives to that (including the one which uses animation events). As far as I can tell, they are about changes to the actual DOM. I’m more interested in attribute changes to a particular DOM element, so I don’t think that’s it. Certainly in my experimenting it doesn’t seem to work.

I would like to do this without jQuery.

Thanks

like image 861
Manngo Avatar asked Jan 02 '17 10:01

Manngo


2 Answers

You need MutationObserver, Here in snippet I have used setTimeout to simulate modifying attribute

var element = document.querySelector('#test');
setTimeout(function() {
  element.setAttribute('data-text', 'whatever');
}, 5000)

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if (mutation.type === "attributes") {
      console.log("attributes changed")
    }
  });
});

observer.observe(element, {
  attributes: true //configure it to listen to attribute changes
});
<div id="test">Dummy Text</div>
like image 116
Satpal Avatar answered Oct 12 '22 06:10

Satpal


This question is already answered, but I'd like to share my experiences, because the mutation observer did not bring me the insights in needed.

Note This is some kind of hacky solution, but for (at least) debugging purposes quite good.

You can override the setAttribute function of a particalar element. This way you can also print the callstack, and get an insight of "who" changed the attribute value:

// select the target element
const target = document.querySelector("#element");
// store the original setAttribute reference
const setAttribute = target.setAttribute;
// override setAttribte
target.setAttribute = (key: string, value: string) => {
  console.trace("--trace");
  // use call, to set the context and prevent illegal invocation errors
  setAttribute.call(target, key, value); 
};
like image 5
scipper Avatar answered Oct 12 '22 04:10

scipper