OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Create a WeakSet of all elements whose layout overflows documentElement

  • Thread starter Thread starter David Bradshaw
  • Start date Start date
D

David Bradshaw

Guest
I want to create a WeakSet of all elements that are not 100% contained within the css layout bounds of the document root (<html> tag). I need to it to update in real time and not have a huge hit on browser performance.

To achieve this I used the intersectionObserver API as follows below and this creates my WeakSet with all the elements I expect when I pass it document.querySelectorAll('body *')

My problem is that when I want to test if an element is in my WeakSet, I get the correct answer in Safari. However, both Chrome and FireFox always return false when I check a matching element using overflowedElements.has(el)

This appears to be due to Chrome/FireFox incorrectly creating a separate reference to the element via the IntersectionObserverEntry: target property, which then means that I end up with two non-matching references to the same element.

So I guess my question is how can I cheaply get the correct element references into my WeakSet, so I can match them in all browsers?

Code:
const options = {
  root: document.documentElement,
  rootMargin: '0px',
  threshold: 1,
}

const overflowedElements = new WeakSet()

const callback = (entries) => {
  entries.forEach((entry) => {
    if (entry.intersectionRatio !== 1) {
      overflowedElements.add(entry.target)
    } else {
      overflowedElements.delete(entry.target)
    }
  })
  console.log('overflowedElements', overflowedElements)
}

const observer = new IntersectionObserver(callback, options)

export const observeOverflow = (nodeList) => {
  nodeList.forEach((el) => {
    observer.observe(el)
  })
}

export const isOverflowed = (el) => overflowedElements.has(el)

<p>I want to create a <code>WeakSet</code> of all elements that are not 100% contained within the css layout bounds of the document root (<code><html></code> tag). I need to it to update in real time and not have a huge hit on browser performance.</p>
<p>To achieve this I used the <strong>intersectionObserver API</strong> as follows below and this creates my WeakSet with all the elements I expect when I pass it <code>document.querySelectorAll('body *')</code></p>
<p>My problem is that when I want to test if an element is in my WeakSet, I get the correct answer in <strong>Safari</strong>. However, both <strong>Chrome</strong> and <strong>FireFox</strong> always return <code>false</code> when I check a matching element using <code>overflowedElements.has(el)</code></p>
<p>This appears to be due to Chrome/FireFox incorrectly creating a separate reference to the element via the <a href="https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry/target" rel="nofollow noreferrer">IntersectionObserverEntry: target</a> property, which then means that I end up with two non-matching references to the same element.</p>
<p>So I guess my question is how can I cheaply get the correct element references into my WeakSet, so I can match them in all browsers?</p>
<pre><code>const options = {
root: document.documentElement,
rootMargin: '0px',
threshold: 1,
}

const overflowedElements = new WeakSet()

const callback = (entries) => {
entries.forEach((entry) => {
if (entry.intersectionRatio !== 1) {
overflowedElements.add(entry.target)
} else {
overflowedElements.delete(entry.target)
}
})
console.log('overflowedElements', overflowedElements)
}

const observer = new IntersectionObserver(callback, options)

export const observeOverflow = (nodeList) => {
nodeList.forEach((el) => {
observer.observe(el)
})
}

export const isOverflowed = (el) => overflowedElements.has(el)
</code></pre>
 

Latest posts

Top