
Show HN: In-view.js – Get notified when DOM elements enter or exit the viewport - Heqx
https://github.com/camwiegert/in-view
======
cdata
There is an emerging standard called Intersection Observer that addresses the
same use case: [https://github.com/WICG/IntersectionObserver/blob/gh-
pages/e...](https://github.com/WICG/IntersectionObserver/blob/gh-
pages/explainer.md)

This is a really useful problem to solve. But, I would personally prefer to
solve it with a polyfill for a standardized approach that will eventually
receive native implementation.

~~~
Heqx
I hear you. But, isn't this just an editor's draft spec? Only Chrome and
Android have done any implementation at all. So, as far as I can tell, there's
a chance this will never be fully implemented? And, because it's a draft, the
spec could change significantly. Is that right?

~~~
spankalee
A spec being draft seems like an odd reason to ignore it and do a completely
different API.

Intersection Observer has been implemented in Chrome since 51, and Opera since
38. It's currently being implemented in Firefox (
[https://bugzilla.mozilla.org/show_bug.cgi?id=1243846](https://bugzilla.mozilla.org/show_bug.cgi?id=1243846)
), and is "likely" from Edge ([https://developer.microsoft.com/en-
us/microsoft-edge/platfor...](https://developer.microsoft.com/en-us/microsoft-
edge/platform/status/intersectionobserver/) ).

in-view.js's API is certainly less likely to be the cross-platform API than
Intersection Observer. Also, plenty of APIs are implemented by browsers at the
editor's draft stage.

~~~
Heqx
I was sincerely asking all of those questions. I'm not very familiar with the
process these specs go through to reach adoption.

------
wldlyinaccurate
I know that this type of functionality is useful, but please consider the
performance implications before doing anything like this. Non-native
implementations (i.e. not IntersectionObserver) _always_ use properties and
methods that cause style and layout calculations which have a significant
performance impact on low-powered devices.

A more comprehensive list is here[1], but the main culprits are
HTMLElement.offset{Width,Height}, Element.client{Width,Height}, and
Window.getComputedStyle(). Avoid these, _especially_ on events like scroll.
You will ruin the experience for many of your users.

[1]
[https://gist.github.com/paulirish/5d52fb081b3570c81e3a](https://gist.github.com/paulirish/5d52fb081b3570c81e3a)

~~~
gcb0
and it's impossible to achieve it without probing those attributes.

some advertising libraries solve that, since the advertising industry deals in
in-view ad impressions for a few years now, by being smart about when to do
it. the best one is called safeFrames. others like moat detect if the user has
a fast computer, abuse it to no end, and then extrapolate the results for the
whole audience.

i expect all of them to move to the native APIs soon (but Android
fragmentation will make it slow)

------
vvoyer
There are a lot of edge cases to handle when creating a library like that and
I cannot see them dealt with in this library.

More than three years ago I created in-viewport and have perfected it since.
[https://github.com/vvo/in-viewport](https://github.com/vvo/in-viewport) it's
used on fortune 500 websites along with my lazyloader
([https://github.com/vvo/lazyload](https://github.com/vvo/lazyload)).

[https://github.com/camwiegert/in-
view/issues/7](https://github.com/camwiegert/in-view/issues/7)

------
afandian
I hope this gets used for good, not evil. Lots of sites (you know, _those_
sites, they crop on on HN from time to time) flash up "give me your email
address so I can send you spam" boxes before I can read the blog post. Or when
it thinks I've gone somewhere else when in fact I just opened it in a new tab.
Or if a momentarily switched away. I mostly close blogs that aggressively try
to sell me things, but sometimes I want to read the content.

Conversations about what's an app and what's a document aside, I'd much rather
documents didn't know anything about how they were being displayed.

~~~
nathancahill
It's unfortunate. However, it's been shown over and over to have the best
conversion rate for getting people's emails, so it's a trend that's only going
to become more popular from here (until the next high conversion pattern is
developed).

~~~
Eric_WVGG
Not necessarily. Google just announced that, in the name of accessibility,
they will start penalizing sites that use them.

[https://webmasters.googleblog.com/2016/08/helping-users-
easi...](https://webmasters.googleblog.com/2016/08/helping-users-easily-
access-content-on.html)

~~~
globuous
I think it's only for mobile versions of a website:

"To improve the mobile search experience, after January 10, 2017, pages where
content is not easily accessible to a user on the transition from the mobile
search results may not rank as highly."

They define what is acceptable and not right after. I like the move though !

------
dmbass
Babel and webpack are megaoverkill for this and account for a good chunk of
the 2k gzipped size. The actual library code is barely 140SLOC. There's a lot
of room for improvement if this is intended to be a real standalone library
(vs. a webpack/babel test).

~~~
johnhenry
I've found rollup, [https://rollupjs.org/](https://rollupjs.org/), to be
really useful for this.

~~~
jonahx
This looks nice. Is it as battle-tested as browserify?

~~~
JasonSage
tl;dr—don't use rollup with large untested dependencies

I've had projects that got really strange error messages when using rollup
that completely went away when I switched back to Babel.

One "issue" with rollup is that it is not 100% semantically correct. Neither
is Babel in all cases, but the creator argues that if you're not following
exact semantics now, you're relying on your tests to ensure proper behavior,
so use something that is at least more minimal and keeps your bundle size
down.

So when you're writing code and bundling with rollup, you can pretty much
ensure everything works fine, but as soon as you pull in an extensive third-
party library you have no assurances that it has been tested with rollup and
will work correctly in all cases. In the worst case, it will seem to work fine
but in weird situations will actually error out. This was my experience with
rollup.

~~~
JasonSage
I should clarify on my above comment, in rollup the semantics don't matter as
much but if you're using Bublé instead of Babel, the semantics may very well
come into play. In either case, I didn't have luck on a project until I moved
fully to webpack+Babel.

------
iamleppert
Whenever you attach an event handler on scroll, it can impact page performance
because the javascript needs to be evaluated before the scroll event can
continue AFAIK...going from some old Paul Irish talk on performance.

The #1 killer he found responsible for "jankiness" (that horrible scroll
feeling where the page scroll is unresponsive and not 60 fps smooth) is by
people attaching event handlers on the scroll event that take more than a few
ms to complete, thus reducing the frame rate of the page.

It seems like this library is throttling the evaluation of the event handler
but you still need to be careful as to not solve one performance problem and
create another. I know I personally _hate_ slow scrolling web pages.

This seems like something that should be implemented in some as yet unreleased
CSS selector. But that still won't stop people from abusing it.

~~~
JasonSage
Whenever I rely on scroll information, I store the event info I need on the
scroll event in some variable, and the logic that would normally be placed in
the callback goes in a separate requestAnimationFrame loop. This way, even if
it takes a few ms, it doesn't impact the scroll speed of the page. I wish more
developers did this.

~~~
Senji
Ah the good old "GET OFF THE UI THREAD!"

------
wamaral
Only yesterday I implemented this in an application, although a bit simpler
(is the user < n pixels from the bottom of the document? then render more
heavy stuff) so yeah, that's a pretty recurrent use case for a library like
that.

~~~
iamleppert
That only works for content that is statically (absolute) positioned?

------
incogitomode
I made something similar for use with Knockout.js. Love your clear code and
efficient implementation! I will probably swap out my core logic for yours.

Some here have mentioned the webpack overhead, and suggested rollup.js. I've
had great results with rollup for these teeny-tiny browser-focused projects.

------
obihill
Definitely a problem that needs solving, but we run the risk of implementing
too many 'bite-size' libraries with code that could probably serve better as
helper extensions to already existing toolkits e.g. jQuery, underscore, etc.

------
hiphopyo
Similar to [https://github.com/customd/jquery-
visible](https://github.com/customd/jquery-visible) which I use a lot.

------
angry-hacker
Won't this be a performance killer?

~~~
tanto
Depends on how you use it and on how much elements. I am not sure if this is
even worth to be a library. Sometimes I am wondering why people want to use a
lib for everything.

~~~
bikamonki
I agree, many times a library isn't necessary. In backbone.js I solved this
with an interval triggering a global event which sends current scroll pos to
all listening views.

------
johnhenry
Interesting project. I wonder if you might be willing to outline a few use
cases?

~~~
andrewbarba
One of the best use cases is lazy loading expensive data until the div is
visible. Image loading, or even fetching a resource. You essentially get this
for free in native apps (iOS/Android with recycled views) but there hasn't
been a great way to accomplish this on the web.

Note: this is definitely not the same as a recycled view. But can help
accomplish one aspect

~~~
talklittle
Yes, lazy loading is a good use case.

Echo.js
([https://github.com/toddmotto/echo](https://github.com/toddmotto/echo)) is
another small no-dependency library (1.89 KB minified), which detects elements
appearing on screen, and goes a step further to swap the "src" attribute with
a placeholder for lazy loading and unloading.

Disclosure: I've submitted a pull request to it.

