Skip to content

Instantly share code, notes, and snippets.

@diachedelic
Last active March 23, 2023 01:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diachedelic/b026fdd168c8af8cd8ac5cb914e7b3cc to your computer and use it in GitHub Desktop.
Save diachedelic/b026fdd168c8af8cd8ac5cb914e7b3cc to your computer and use it in GitHub Desktop.
React to changes in an element's width.
function watch_width(callback, element) {
// Watch the width of the 'element' for changes, calling 'callback' whenever it
// changes. A 'stop' function is returned, which should be called when the
// watcher is no longer required.
let width;
let observer = new ResizeObserver(function on_resize(entries) {
// Removal of the element from the DOM tree triggers an event, but we are not
// interested in that. We only want to know when the width visibly changes.
if (
document.body.contains(element)
&& entries[0].contentRect.width !== width
) {
// A resize event is always triggered when the element is first observed. That
// is not useful to us.
if (width !== undefined) {
// The element has been resized, so we call the callback.
// We must be careful, however, because if the callback causes the element to be
// resized again then the ResizeObserver will emit an error such
// as "ResizeObserver loop limit exceeded" (in Chrome) or "ResizeObserver loop
// completed with undelivered notifications" (in Safari). These errors are
// unusual in that they are only reported to window.onerror, and not the the
// DevTools console. They are mostly benign, yet can overwhelm up our remote
// error reporting so we work to avoid them.
// Firstly, stop observing the element's size and call the callback. After
// rendering has completed, start observing again. A pause is necessary to
// avoid a "loop limit exceeded" error.
observer.disconnect();
callback();
setTimeout(function () {
if (observer !== undefined) {
observer.observe(element);
}
}, 0);
}
width = entries[0].contentRect.width;
}
});
observer.observe(element);
return function stop() {
observer.disconnect();
observer = undefined;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment