Custom width change event with Mutation Observers

created for answer to http://stackoverflow.com/questions/29909400/is-there-a-event-invoked-when-a-blocks-width-changes

by UselessCode

HTML

<div id="foo">foo</div>

CSS

#foo {
    border: 2px solid #f30;
    width: 100px;
    height: 100px;
    transition: width 1s;
}

JavaScript

let foo = document.getElementById('foo');
const addWidthChangeEvent = function (element) {
  let oldWidth = element.style.width,
    observer = new MutationObserver(mutations => {
      mutations.forEach(mutation => {
        if (mutation.target === element &&
            mutation.attributeName === 'style' &&
            oldWidth !== element.style.width) {
          oldWidth = element.style.width;
          element.dispatchEvent(new Event('widthChange'));
        }
      });    
    });
   
  // configure the observer, just look for attribute changes:
  const config = {
    attributes: true
  };
   
  observer.observe(element, config);
};
 

// add the new widthChange event to foo
addWidthChangeEvent(foo);

// add a listener for the new event
foo.addEventListener('widthChange', event => {
  foo.textContent = foo.style.width;
}, false);


const randomInt = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1)) + min;
};

// change the width every 2 seconds
setInterval(() => {
  let newWidth = randomInt(4, 30) * 10;
    foo.style.width = newWidth + 'px';
}, 2000);