npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

intersection-observer

v0.12.2

Published

A polyfill for IntersectionObserver

Downloads

6,642,468

Readme

⚠️ This polyfill was originally hosted in the IntersectionObserver spec repo. Refer to that repo for commit history.

IntersectionObserver polyfill

This library polyfills the native IntersectionObserver API in unsupporting browsers. See the API documentation for usage information.

Installation

You can install the polyfill via npm or by downloading a zip of this repository:

npm install intersection-observer

Adding the polyfill to your site

The examples below show various ways to add the IntersectionObserver polyfill to your site. Be sure to include the polyfill prior to referencing it anywhere in your JavaScript code.

Using <script> tags in the HTML:

<!-- Load the polyfill first. -->
<script src="path/to/intersection-observer.js"></script>

<!-- Load all other JavaScript. -->
<script src="app.js"></script>

Using a module loader (e.g. Browserify or Webpack):

// Require the polyfill before requiring any other modules.
require('intersection-observer');

require('./foo.js');
require('./bar.js');

Configuring the polyfill

It's impossible to handle all possible ways a target element could intersect with a root element without resorting to constantly polling the document for intersection changes.

To avoid this extra work and performance penalty, the default configuration of the polyfill optimizes for the most common IntersectionObserver use cases, which primarily include target elements intersecting with a root element due to:

  • User scrolling.
  • Resizing the window.
  • Changes to the DOM.

All of the above can be handled without polling the DOM.

There are, however, additional use cases that the default configuration will not detect. These include target elements intersecting with a root element due to:

  • CSS changes on :hover, :active, or :focus states.
  • CSS changes due to transitions or animations with a long initial delay.
  • Resizable <textarea> elements that cause other elements to move around.
  • Scrolling of non-document elements in browsers that don't support the event capture phase.

If you need to handle any of these use-cases, you can configure the polyfill to poll the document by setting the POLL_INTERVAL property. This can be set either globally or on a per-instance basis.

Enabling polling for all instances:

To enable polling for all instances, set a value for POLL_INTERVAL on the IntersectionObserver prototype:

IntersectionObserver.prototype.POLL_INTERVAL = 100; // Time in milliseconds.

Enabling polling for individual instances:

To enable polling on only specific instances, set a POLL_INTERVAL value on the instance itself:

var io = new IntersectionObserver(callback);
io.POLL_INTERVAL = 100; // Time in milliseconds.
io.observe(someTargetElement);

Note: the POLL_INTERVAL property must be set prior to calling the .observe method, or the default configuration will be used.

Ignoring DOM changes

You can also choose to not check for intersections when the DOM changes by setting an observer's USE_MUTATION_OBSERVER property to false (either globally on the prototype or per-instance)

IntersectionObserver.prototype.USE_MUTATION_OBSERVER = false; // Globally

// for an instance
var io = new IntersectionObserver(callback);
io.USE_MUTATION_OBSERVER = false;

This is recommended in cases where the DOM will update frequently but you know those updates will have no effect on the position or your target elements.

iframe support

Same-origin iframes

Same-origin iframes are supported by the polyfill out of the box.

Cross-origin iframes

Additional code and configuration are required to support cross-origin iframes, both on the iframe and host sides.

The setup is as following:

  1. The host and iframe will establish a messaging channel.
  2. The host will setup its own IntersectionObserver instance for the cross-origin iframe element. It can either use the this polyfill or any other approach. For each IntersectionObserverEntry for the iframe it will forward intersection data to the iframe via messaging.
  3. The iframe will load the polyfill and configure it by calling the _setupCrossOriginUpdater() method. It will call the provided callback whenever it receives the intersection data from the the parent via messaging.

A hypothetical host code:

function forwardIntersectionToIframe(iframe) {
  createMessagingChannel(iframe, function(port) {
    var io = new IntersectionObserver(function() {
      port.postMessage({
        boundingClientRect: serialize(boundingClientRect),
        intersectionRect: serialize(intersectionRect)
      });
    }, {threshold: [0, 0.1, ..., 1]});
    io.observe(iframe);
  });
}

Notice that the host should provide a threshold argument for the desired level of precision. Otherwise, the iframe side may not update as frequently as desired.

A hypothetical iframe code:

createMessagingChannel(parent, function(port) {
  if (IntersectionObserver._setupCrossOriginUpdater) {
    var crossOriginUpdater = IntersectionObserver._setupCrossOriginUpdater();
    port.onmessage = function(event) {
      crossOriginUpdater(
        deserialize(event.data.boundingClientRect),
        deserialize(event.data.intersectionRect)
      );
    };
  }
});

Limitations

This polyfill does not support the proposed v2 additions, as these features are not currently possible to do with JavaScript and existing web APIs.

Browser support

The polyfill has been tested and known to work in the latest version of all browsers.

Legacy support is also possible in very old browsers by including a shim for ES5 as well as the window.getComputedStyle method. The easiest way to load the IntersectionObserver polyfill and have it work in the widest range of browsers is via polyfill.io, which will automatically include dependencies where necessary:

<script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver"></script>

With these polyfills, IntersectionObserver has been tested and known to work in the following browsers:

Running the tests

To run the test suite for the IntersectionObserver polyfill, open the intersection-observer-test.html page in the browser of your choice.

If you run the tests in a browser that supports IntersectionObserver natively, the tests will be run against the native implementation. If it doesn't, the tests will be run against the polyfill.