'How to detect when the div element width change (not window resize) in JS?

I have a scenario, if div element width changes, i need to perform some functionality. So is there any way to detect that element width changes (not window resize).

for Example, I have a DIV element with the width 300px and my window is 800px while rendering the page. When i trigger a function, i changed the div element width to 400px, so for that default width change i need to perform some actions, so is there any way to detect in pure javascript for the element size change ?



Solution 1:[1]

You can use a MutationObserver. Consider the following example that will let you know when the <p> tag is resized manually or when you click the "Resize" button. Any attribute mutation will trigger the observer so you will need to filter by what you want.

const p = document.querySelector("p");
const button = document.querySelector("button");

const p$ = new MutationObserver((mutationList, observer) => {
  for (mutation of mutationList) {
    console.log(mutation);
  }
});

p$.observe(p, {
  attributes: true,
  childList: false,
  subtree: false
});

button.addEventListener("click", () => {
  p.style.width = "100px";
});
.wrapper {
  width: 400px;
}

.resizable {
  resize: both;
  overflow: scroll;
  border: 1px solid black;
}
<div class="wrapper">
  <p class="resizable">Hello</p>
  <button>Resize</button>
</div>

Solution 2:[2]

You could use a MutationObserver instance and look for any change of the style attribute

var element = document.getElementById('d');

var observer = new MutationObserver(function() {
   console.log("You changed the style") 
});


observer.observe(element, { attributeFilter: ['style'] });


setTimeout(()=>{
   element.style.width = '400px';
}, 2000)
#d {
   width: 300px;
   height: 300px;
   background: #9bc;
}
<div id="d"></div>

If you instead apply a class with the given width then listen to any change of the class in the attributeFilter.

Solution 3:[3]

The perfect solution would be a ResizeObserver, because it's more efficient than polling, and can detect changes due to dynamic CSS units, transitions, animations, etc. as well.

And as of 2022, it's already supported in all mainstream browsers.

const elem = document.querySelector('#sizeobserver')

new ResizeObserver(console.log).observe(elem)
#sizeobserver {
   resize: both;
   overflow: hidden;
   border: 1px solid black;
}
<div id="sizeobserver">Resize me!</div>

To ignore height changes, you can check for the width property of the contentRect. Now only the width's changes get logged:

const elem = document.querySelector('#sizeobserver')
{ // <--Just to encapsulate prevWidth
  let prevWidth
  new ResizeObserver(changes => {
    for(const change of changes){
      if(change.contentRect.width === prevWidth) return
      prevWidth = change.contentRect.width

      //Code here:
      console.log(change)
    }
  }).observe(elem)
}
#sizeobserver {
   resize: both;
   overflow: hidden;
   border: 1px solid black;
}
<div id="sizeobserver">Resize me!</div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 zero298
Solution 2 Fabrizio Calderan
Solution 3