I want to call my code when the width of the block I listen to changes. How to?
onresize
is invoked only when the size of the window changes.
An option can be to use ResizeObserver:
Observes all width changes.
JS:
var foo = document.getElementById('foo');
var observer = new window.ResizeObserver(entries =>
console.log(entries[0].contentRect.width));
observer.observe(foo);
}
Stackblitz in Angular
As you mentioned, there is no resize
event for elements on the page, just for window
.
You can however use Mutation Observers to detect changes in an element:
const foo = document.querySelector('#foo');
let oldWidth = window.getComputedStyle(foo).getPropertyValue('width');
const observer = new MutationObserver(function(mutations) {
mutations.forEach(mutation => {
if (mutation.target === foo &&
mutation.attributeName === 'style' &&
oldWidth !== foo.style.width) {
foo.textContent = 'Width changed from ' +
oldWidth + ' to ' + foo.style.width;
oldWidth = foo.style.width;
}
});
});
// configure the observer, just look for attribute changes:
const config = {
attributes: true
};
// start observing
observer.observe(foo, config);
// change the width after a second so we can detect it
setTimeout(() => {
foo.style.width = '150px';
}, 1000);
#foo {
border: 2px solid #f30;
width: 100px;
height: 100px;
transition: width 1s;
}
<div id="foo">foo</div>
With a little more work you can create a function that will add a custom event to the element you want to detect width changes on:
const addWidthChangeEvent = function(element) {
let oldWidth = window.getComputedStyle(element).getPropertyValue('width');
const 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);
};
const foo = document.getElementById('foo');
// 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);
#foo {
border: 2px solid #f30;
width: 100px;
height: 100px;
transition: width 1s;
}
<div id="foo">foo</div>
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