I'm trying to create an observer that triggers when the bounding rect of an element changes (a BoundingClientRectObserver), and this is what I have so far:
customElements.define(
'bounding-client-rect-observer-helper',
class extends HTMLDivElement {
disconnectedCallback () { this.dispatchEvent(new Event('$disconnected')) }
},
{extends: 'div'}
)
class BoundingClientRectObserver {
#intersectionObserver
#helperElement
#timeoutId
constructor (element, callback, startNow=true) {
if (typeof element == 'string') {
element = document.querySelector(element)
}
this.element = element
this.callback = callback
this.#helperElement = document.createElement(
'div', {is: 'bounding-client-rect-observer-helper'}
)
this.#helperElement.style.position = 'fixed'
this.#helperElement.style.visibility = 'hidden'
this.#intersectionObserver = new IntersectionObserver(
entries => this.#debouncedCallback(entries),
{root: this.element, threshold: [0,1.0]}
)
this.disconnected = this.disconnected.bind(this)
this.running = false
if (startNow) this.start()
}
start () {
if (this.running) return
this.element.append(this.#helperElement)
this.#helperElement.addEventListener('$disconnected', this.disconnected)
this.#intersectionObserver.observe(this.#helperElement)
this.running = true
}
#innerCallback () {
const rect = this.element.getBoundingClientRect()
this.#helperElement.style.width = rect.width + 'px'
this.#helperElement.style.height = rect.height + 'px'
this.#helperElement.style.left = rect.left + 'px'
this.#helperElement.style.top = rect.top + 'px'
this.callback(rect)
}
#debouncedCallback (entries) {
console.log(entries)
clearTimeout(this.#timeoutId)
this.#timeoutId = setTimeout(() => this.#innerCallback(), 200)
}
disconnected () {
if (this.running) {this.element.append(this.#helperElement)}
}
stop () {
if (!this.running) return
this.#intersectionObserver.unobserve(this.#helperElement)
this.#helperElement.removeEventListener('$disconnected', this.disconnected)
this.#helperElement.remove()
this.running = false
}
}
I'm adding a helper element to the root element (the one I want to check if its bounding client rect changes) with the same bounding client rect, since in the IntersectionObserver docs it says that the element to observe should be a descendant of the root element. So in theory, everytime the size or position of the root element changes, the callback should be called, but this is not happening, and I suspect it's because bounding client rects in entries (I'm printing the entries in #debouncedCallback function) are empty. can you see where I got it wrong?