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

[hook-intersection] intersects state should be based on intersectionRatio and isIntersecting #32

Open
lettertwo opened this issue Sep 17, 2019 · 1 comment
Labels
Type: Bug Something isn't working

Comments

@lettertwo
Copy link
Contributor

lettertwo commented Sep 17, 2019

Description

Using this hook statefully, like:

const [intersects, ref] = useIntersection();

provides a boolean intersects value that is derived from the isIntersecting value of the underlying IntersectionObserverEntry.

In the simple case (as above), this is fine, but if thresholds are defined, expectations change:

const [intersects, ref] = useIntersection({threshold: 0.75});

Here, the expectation is that intersects will be true only if the intersectionRatio is 0.75 or greater.

This works as expected in Chrome, but not in Firefox. As it turns out, this may be due to a chromium bug. Interestingly, MDN suggests that the chromium behavior is correct, but it seems the spec actually sides with Firefox.

Steps to Reproduce

View the stateful example in Firefox.

Expected Result

The example stays red until the intersection ratio meets the provided threshold.

Actual Result

The example turns green as soon as any intersection occurs. This results in the example always being green, but if you modify the example to move the element out of the containing view, you can see in the DOM that it switches to red.

Additional Context

We most likely need to update our intersects state calculation to compare the provided thresholds to intersectionRatio, not just base it on isIntersecting. Note that it's possible to define multiple thresholds, like:

const [intersects, ref] = useIntersection({threshold: [0.5, 0.6, 0.7, 0.8, 0.9, 1]});

so the calculation must account for this case.

@lettertwo lettertwo added the Type: Bug Something isn't working label Sep 17, 2019
@presto2116
Copy link
Contributor

@lettertwo Looking into this issue now.
For goodwill-halloween my solution was to use the intersectionRatio and set my state inside of the hook.
Maybe instead of returning boolean isIntersecting. we return the ratio and let the user handle the threshold.
Chrome and Firefox both process intersectionRatio correctly but do not process isIntersecting the same way.

  const [intersectionState, setIntersectionState] = useState({
    intersectionRatio: 0,
    boundingClientRect: 0,
  });

useIntersection(
    ref,
    ({ intersectionRatio, boundingClientRect }) => {
      setIntersectionState({ intersectionRatio, boundingClientRect });
    }
  );

instead of

const [intersects, ref] = useIntersection({threshold: [0.5, 0.6, 0.7, 0.8, 0.9, 1]});

return the intersectionRatio

const [intersectionRatio, ref] = useIntersectionRatio();

and have the user use that accordingly. Looking through the code, it doesn't seem like much would change. you can still pass in config and handle stateful/stateless examples. and it eliminates the need for passing in different thresholds into the hook.
It is a pain that a simple boolean wont be returned, but the boolean doesn't even work in this case so updating everything will be for the better. Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants