Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cant seem to have this polyfill work in screen size <768px #300

Closed
tifidy opened this issue May 27, 2018 · 11 comments
Closed

Cant seem to have this polyfill work in screen size <768px #300

tifidy opened this issue May 27, 2018 · 11 comments
Labels

Comments

@tifidy
Copy link

tifidy commented May 27, 2018

I am using this polyfil to lazyload images that works marvelously but somehow when I resize window down to less than 768px. Polyfil observes images but does not throw isIntersecting:true. It works fine when browser is actually supporting IntersectionObserver. Any help appriciated .

Thank you!

@philipwalton
Copy link
Member

Can you provide a demo showing the problem? In general the polyfill should work for any screen size. I suspect in your case there may be a media query doing something you're not accounting for (or something like that).

@ybentz
Copy link

ybentz commented Jan 9, 2019

I've just encountered a case where on iOS Safari & Chrome isIntersecting worked but had a bug and when I switched to using intersectionRatio everything works as expected. My scenario is a bit complicated so not sure I'll be able to isolate it easily but I can try creating a pen for it.

In my case I have almost full width cards that are horizontally scrollable using the newer CSS scroll-snap API and are observed with an intersection threshold of 0.53 so there's only 1 card intersecting at all times. isIntersecting properly returns true for the currently visible card but all previously visible cards still report that they're intersecting until something on the screen is clicked (maybe due to focus change? I tried using POLL_INTERVAL but that didn't help). When I switched to using entry.intersectionRatio > 0.53 everything works great.

I wonder if this issue is related so if still relevant, @tifidy can you check if using intersectionRatio works for you?

@philipwalton
Copy link
Member

@ybentz a repo would be helpful.

...isIntersecting worked but had a bug and when I switched to using intersectionRatio everything works as expected.

Can you add some more detail here? What do you mean by "worked by had a bug"?

@ybentz
Copy link

ybentz commented Apr 24, 2019

@philipwalton I can try and get a repro for it.

Can you add some more detail here? What do you mean by "worked by had a bug"?

I described the bug in detail on the next paragraph but I'll try to simplify.
I have a horizontal list of full screen width elements, I only want 1 of them to intersect at all times while scrolling the list.
Using isIntersecting and intersection threshold of 0.53, while scrolling through the list, elements that intersected previously still report that they're intersecting and only got updated to the correct value when screen was tapped (anywhere). When switching to using entry.intersectionRatio > 0.53 instead, everything works as expected having only 1 element reported as intersecting at all times.

@philipwalton
Copy link
Member

isIntersecting is expected to report true if any part of the element is intersecting, even if just the borders are touching. Is it possible your cards are positioned at the exact borders of the viewport? (This is why a repro would be helpful).

Also, if the behavior the same with and without the polyfill?

@ybentz
Copy link

ybentz commented Apr 24, 2019

isIntersecting is expected to report true if any part of the element is intersecting

Even with the intersection threshold set to < 1? That's why I mentioned setting the threshold to 0.53.

Also, if the behavior the same with and without the polyfill?

I think it's only with the polyfill.
It only happened on iOS which did not support intersection observer last time I encountered the bug. Anywhere else I checked (Chrome, Firefox on Mac + Chrome on Android) it worked well using isIntersecting and the mentioned threshold.
Tbh, I didn't debug it too much because I worked around it using intersectionRatio and I was somewhat limited with time.

@philipwalton
Copy link
Member

Even with the intersection threshold set to < 1?

Yep, here's how it's defined in the spec: https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-isintersecting

Tbh, I didn't debug it too much because I worked around it using intersectionRatio and I was somewhat limited with time.

Intersection ratio is definitely the preferred way to check. The isIntersecting property is only useful in cases where the intersection threshold is set to 0 because it's possible that an element is intersecting but has an intersection ratio of 0 (e.g. a zero-sized element, or an element that only touches on the border).

@ybentz
Copy link

ybentz commented Apr 25, 2019

Huh, that's good to know! And it's also really interesting then. A few things to note:

  1. If this is the case then I can't explain how/why my setup worked properly with isIntersecting on every browser except on iOS. As I mentioned, my list items are almost full width but I only had 1 item intersecting at all times meaning that an item that was definitely intersecting with the document was reporting isIntersecting === false.

  2. When trying to understand how to work with it I remember reading as much as I could about the intersection observer API, I did not read the official spec but I did read the relevant MDN page which specifically contradicts this. They even explain it with an example.

For example, if you want to be informed every time a target's visibility passes backward or forward through each 25% mark, you would specify the array [0, 0.25, 0.5, 0.75, 1] as the list of thresholds when creating the observer. You can tell which direction the visibility changed in (that is, whether the element became more visible or less visible) by checking the value of the isIntersecting property on the IntersectionObserverEntry passed into the callback function at the time of the visibility change. If isIntersecting is true, the target element has become at least as visible as the threshold that was passed. If it's false, the target is no longer as visible as the given threshold.

  1. As for my iOS issue, I for sure had items that were no longer intersecting at all with the document but were still reporting that they were intersecting. for example, when the page loads the 1st item is intersecting, then if the list is scrolled passed the 2nd right to the 3rd all first 3 items were still reporting that they're intersecting even though the 1st was definitely not anymore.

@philipwalton
Copy link
Member

Hmmm, yeah, MDN is wrong here.

As for your iOS issue, it's hard to say without seeing a repro. It's possible that iOS has a bug with one of the APIs the polyfill uses (e.g. getBoundingClientRect()) when using snap points.

Are you still seeing the issue on 12.1+? Safari and iOS have a native implementation of IntersectionObserver now, so if the issue is gone I'm happy to assume it was just a Safari bug that's been fixed.

@ybentz
Copy link

ybentz commented Apr 26, 2019

Are you still seeing the issue on 12.1+?

I don't have access to a physical device atm but I tried on the mac's simulator, on iOS 12.2 everything works just like on any other browser (matches the behavior described on MDN) but on iOS 11.4 I still see the bug I described, using isIntersecting is messed up but using intersectionRatio works well.
So the 2 options are that there's indeed an iOS bug that messes up the polyfill or that there's a bug in the polyfill since the only browsers I tested on that don't have native support are on iOS.
Either way doesn't seem like it's going to be a problem soon since the new iOS versions' adoption rate is usually great.

Might be unrelated to the bug but I'm still pretty confused about isIntersecting. Thinking about it more, it makes no sense for isIntersecting to consider the intersection threshold since the threshold can be an array of values but from what I can tell by playing around with the thresholds and my app, all browsers are behaving according to the MDN description.
I just tried setting the threshold to [0.25, 0.53, 0.75] and then to [0.1, 0.25, 0.53, 0.75] and isIntersecting is reporting intersection according to the first value (0.25 and then 0.1).

@miketaylr
Copy link
Member

Either way doesn't seem like it's going to be a problem soon since the new iOS versions' adoption rate is usually great.

OK, some 3 years later I think we're good to close here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants