Peekaboo
Fires a one-time event whenever elements of your choice are about to scroll into the viewport. Perfect for triggering animations or for just-in-time asset loading, for example; images, javascript libraries such as twitter and facebook, article comments or 3rd party advertisments.
The more curious amongst you may wish to jump straight to one of the demos:
- A demo that animates 500 list items as they scroll into view
- A demo that covers lazyloading responsive images
At a glance…
- Uses the very fast
IntersectionObserver
API where possible - Fallsback to using a single
scroll
andresize
event in other browsers but hooks intorequestAnimationFrame
to stop scroll jank - Correctly calculates if an observed element is hidden in the overflow of a parent element
- A little over 1k when minified & gzipped
The Peekaboo API
The API was purposely kept small and focused – It contains only two methods, both of which are described below:
<Object> window.peekaboo
An Object window.peekaboo
is made available. It makes public the following API methods.
peekaboo.observe(<Object>)
The peekaboo.observe
method is used to initiate the observation of DOM elements; for example:
The method accepts a configuration Object containing the following attributes:
Attribute | Required | Description |
---|---|---|
pattern |
Yes | A |
callback |
Yes |
A Elements are observed on a one-time-only basis meaning if the element is scrolled out of the observable area and then back in again, the |
fastVisibilityCheck |
No | An optional If you know that none of the observable elements targetted by |
rootMargin |
No | An optional |
Adding observable elements to the DOM dynamically
If no configuration object is passed to the peekaboo.observe
method, the script cycles through the list of currently assigned patterns and recalculates the observable element set for each. This is a useful way to update the scripts
internal element list if potential observable elements have been added to the DOM dynamically.
peekaboo.unobserve(<String>)
Should you no longer need to observe elements, just call the peekaboo.unobserve
method, passing in a String
value representing a CSS Selector previously used when calling peekaboo.observe
.
<Boolean> peekaboo.supported
A Boolean
variable named peekaboo.supported
is made available by the script to enable you to determine if the browser is supported.
Browser support
Modern browsers only (IE10+). The script relies on either the IntersectionObserver
API or a mix of addEventListener
, querySelectorAll
, requestAnimationFrame
and getBoundingClientRect
– which limits it to a more modern browser experience. Hopefully browser uptake for the IntersectionObserver
API will be swift and this script will be obsolete in the near future (caniuse: Intersection Observer).
Loading the script
Add the script to the page source code as shown below. It’s a good idea to add it directly before the closing </body>
tag as it requires the DOM to be populated before initialisation.
“Cuts the mustard” async loading
If you already use an async file loader (such as loadJS) then the following cuts the mustard test can be performed before loading the script:
This is basically the same test performed internally by the script when setting the peekaboo.supported
variable.
This may seem a bit heavy handed but requestAnimationFrame
is often polyfilled and the check for IE9+ needed to be as failsafe as possible.
Performance matters
Any script that’s observing DOM elements will undoubtedly demand CPU cycles but the following speed gains have been integrated:
- Uses the very fast
IntersectionObserver
API where possible - Attempts to reuse the same
IntersectionObserver
instance where possible for all calls topeekaboo.observe
- Batches callbacks i.e. one callback for many elements, not one callback per element
- For browsers that don’t support the
IntersectionObserver
…- Fallsback to using a single
scroll
andresize
event in other browsers but hooks intorequestAnimationFrame
to stop scroll jank - Automatically removes the
scroll
andresize
event handler when no longer needed - Caches element lists to reduce the
querySelectorAll
overhead to a bare minimum when thescroll
/resize
fallback is used - Caches window
height
andwidth
to help avoid layout thrashing - Ships with a
fastVisibilityCheck
option for speeding things up even more
- Fallsback to using a single