-
-
Save diachedelic/b026fdd168c8af8cd8ac5cb914e7b3cc to your computer and use it in GitHub Desktop.
React to changes in an element's width.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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