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

Use 'scroll' and 'resize' DOM events instead of a timer #10

Closed
mvila opened this issue May 15, 2015 · 23 comments
Closed

Use 'scroll' and 'resize' DOM events instead of a timer #10

mvila opened this issue May 15, 2015 · 23 comments

Comments

@mvila
Copy link

mvila commented May 15, 2015

Instead of using a timer it would be great (and CPU saver...) to use 'scroll' and 'resize' DOM events to check the visibility only when it's necessary. https://github.com/Pomax/react-component-visibility does that but it doesn't have the 'containment' feature.

@joshwnj
Copy link
Owner

joshwnj commented May 15, 2015

What I'd like here (but haven't gotten around to yet) is to use both. So we'd have scroll and resize listeners as the main trigger, but also have a timer for the cases where visibility changes without either a scroll or a resize.

With this implemented we'd treat the timer as a fallback and use a much longer delay, making the CPU impact negligible (or, at least: within the control of the developer).

Fancy having a go at that? PRs welcome :)

@mvila
Copy link
Author

mvila commented May 16, 2015

Absolutely, to use both a timer and events would be great. And in this case, perhaps the default 1000 ms delay is fine. Unfortunately, I'm too busy now to help you with the implementation. I hope someone can do it! :)

@joshwnj
Copy link
Owner

joshwnj commented May 16, 2015

I've put a call out on twitter in case anyone would like to volunteer :) otherwise I'll get to it when I next have time

@Ghostavio
Copy link

I can take a look at it, if it's still something you guys want to add :)

@kof
Copy link
Collaborator

kof commented Nov 17, 2015

Or we remove both timer and don't add events. It can be easily done in the user space. I use active=false and do the checks manually in my code. Only user code can really know what it needs to react to and how often.

@mvila
Copy link
Author

mvila commented Nov 17, 2015

@Ghostavio: 👍 :)

@kof: If you remove everything, what would be the point of the module? :)

@kof
Copy link
Collaborator

kof commented Nov 17, 2015

I don't remove "everything", component remains as usefull as before, its a very small api change that makes api lower lever but with less bugs.

@kof
Copy link
Collaborator

kof commented Nov 17, 2015

you want periodical check? its easy

setInterval(::this.refs.sensor.check, 1000)

you want on scroll?

window.addEventListener('scroll', ::this.refs.sensor.check)

you want a scroll with debounce? (you should want it)

import debounce from 'lodash/function/debounce'
window.addEventListener('scroll', debounce(::this.refs.sensor.check, 200))

@kof
Copy link
Collaborator

kof commented Nov 17, 2015

everything you might want to do you can do just in one line of code, its the same line you will use for a fragile option.

@kof
Copy link
Collaborator

kof commented Nov 17, 2015

Also I would think about how to get rid of the imperative .check() call.

@mvila
Copy link
Author

mvila commented Nov 17, 2015

@kof: I think a sensor should be able to work by itself. Imagine if you had to call a check() method on a button to find out if it is clicked or not, it would be wrong don't you think?

@kof
Copy link
Collaborator

kof commented Nov 17, 2015

@mvila in the ideal world you would be right .... in practice I can see lots of issues to make it magically work.

If a tool can't do the magic without side effects, it should not have this magic.

@mvila
Copy link
Author

mvila commented Nov 18, 2015

@kof: Well, listening to scroll and resize events to trigger the visibility check doesn't look too magical to me. If we do that we can increase the timer to 1 sec or remove it completely. It should work in 95% of cases and for the remaining 5% the developer has always the possibility to trigger the checking manually.

@kof
Copy link
Collaborator

kof commented Nov 18, 2015

I know following problems:

  1. List of items, where every item is wrapped into sensor. If we do it with timer, it should be just one for all instances, otherwise even with 1sec timer its hundreds of timers. Same for scroll event listener.
  2. Problem with scroll event listener - it doesn't bubble up to the window or document when some inner container is scrolled. This means we need to attach the listener to the containment element we already have. In case of a list with lots of sensors we run again into listeners amount problem.
  3. Resize event is only possible on window anyways. Container resizes can't be checked as far as I know. We can only try dom mutation observers, which is not always an indication for a resize.

@kof
Copy link
Collaborator

kof commented Nov 18, 2015

I could think of a container component which contains the listeners/timers and communicates with the inner sensors.

@joshwnj
Copy link
Owner

joshwnj commented Nov 18, 2015

I like the idea of 2 separate components, @kof gives some good examples of why you might need that.

What if we said that by default the 2 components come bundled together, but you can opt into separating them and manually associating the trigger with the sensor?

@kof
Copy link
Collaborator

kof commented Nov 18, 2015

Yes its possible. Component "Sensor" and component "Trigger" and a default component which is Sensor wrapped into Trigger.

@botverse
Copy link

botverse commented Dec 9, 2015

I agree with @mvila. The component would aim to be too generic removing all the setup, scroll and resize should be right for the majority of the cases.

As suggested by @kof, for particular cases that differ from that, active={false} and manually manage check is an acceptable solution.

@joshwnj active={false} is already opting out. Would make little sense to have two components for that.

So it seems just right to change the timer by debounced scroll/resize.

@Andarist
Copy link
Contributor

Andarist commented May 5, 2016

https://developers.google.com/web/updates/2016/04/intersectionobserver?hl=en

That would be even more cool, ofc browser support sucks yet.

@kof
Copy link
Collaborator

kof commented May 5, 2016

Cool, I would rename this project to react-intersection-observer and start using IntersectionObserver if supported.

@Andarist
Copy link
Contributor

Andarist commented May 5, 2016

Maybe (and that is strong maybe) I will have some time next week to give it a shot at implementing and testing this.

@eek
Copy link
Collaborator

eek commented Nov 26, 2016

Implemented this in #54 if you guys can have a look, it would be awesome 😁

@joshwnj
Copy link
Owner

joshwnj commented Nov 28, 2016

Thanks @eek ! Will take a look

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

No branches or pull requests

7 participants