Localisation updates from https://translatewiki.net.
[mediawiki.git] / resources / lib / intersection-observer / README.md
blob5a44cd49624e01b2135d5cf4515499081a1725b2
1 # `IntersectionObserver` polyfill
3 This library polyfills the native [`IntersectionObserver`](http://w3c.github.io/IntersectionObserver/) API in unsupporting browsers. See the [API documentation](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) for usage information.
5 - [Installation](#installation)
6 - [Configuring the polyfill](#configuring-the-polyfill)
7 - [Limitations](#limitations)
8 - [Browser support](#browser-support)
9 - [Running the tests](#running-the-tests)
11 ## Installation
13 You can install the polyfill via npm or by downloading a [zip](https://github.com/w3c/IntersectionObserver/archive/gh-pages.zip) of this repository:
15 ```sh
16 npm install intersection-observer
17 ```
19 ### Adding the polyfill to your site
21 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.
23 **Using `<script>` tags in the HTML:**
25 ```html
26 <!-- Load the polyfill first. -->
27 <script src="path/to/intersection-observer.js"></script>
29 <!-- Load all other JavaScript. -->
30 <script src="app.js"></script>
31 ```
33 **Using a module loader (e.g. Browserify or Webpack):**
35 ```js
36 // Require the polyfill before requiring any other modules.
37 require('intersection-observer');
39 require('./foo.js');
40 require('./bar.js');
41 ```
43 ## Configuring the polyfill
45 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.
47 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:
49 - User scrolling.
50 - Resizing the window.
51 - Changes to the DOM.
53 All of the above can be handled without polling the DOM.
55 There are, however, additional use cases that the default configuration will not detect. These include target elements intersecting with a root element due to:
57 - CSS changes on `:hover`, `:active`, or `:focus` states.
58 - CSS changes due to transitions or animations with a long initial delay.
59 - Resizable `<textarea>` elements that cause other elements to move around.
60 - Scrolling of non-document elements in browsers that don't support the event capture phase.
62 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.
64 **Enabling polling for all instance:**
66 To enable polling for all instance, set a value for `POLL_INTERVAL` on the `IntersectionObserver` prototype:
69 ```js
70 IntersectionObserver.prototype.POLL_INTERVAL = 100; // Time in milliseconds.
71 ```
73 **Enabling polling for individual instance:**
75 To enable polling on only specific instances, set a `POLL_INTERVAL` value on the instance itself:
77 ```js
78 var io = new IntersectionObserver(callback);
79 io.POLL_INTERVAL = 100; // Time in milliseconds.
80 io.observe(someTargetElement);
81 ```
83 **Note:** the `POLL_INTERVAL` property must be set prior to calling the `.observe` method, or the default configuration will be used.
85 **Ignoring DOM changes**
87 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)
89 ```js
90 IntersectionObserver.prototype.USE_MUTATION_OBSERVER = false; // Globally
92 // for an instance
93 var io = new IntersectionObserver(callback);
94 io.USE_MUTATION_OBSERVER = false;
95 ```
97 This is recommended in cases where the DOM will update frequently but you know those updates will have no affect on the position or your target elements.
100 ## iframe support
102 ### Same-origin iframes
104 Same-origin iframes are supported by the polyfill out of the box.
107 ### Cross-origin iframes
109 Additional code and configuration are required to support cross-origin iframes,
110 both on the iframe and host sides.
112 The setup is as following:
114 1. The host and iframe will establish a messaging channel.
115 2. The host will setup its own IntersectionObserver instance for the
116 cross-origin iframe element. It can either use the this polyfill or any other
117 approach. For each IntersectionObserverEntry for the iframe it will forward
118 intersection data to the iframe via messaging.
119 3. The iframe will load the polyfill and configure it by calling the
120 `_setupCrossOriginUpdater()` method. It will call the provided callback
121 whenever it receives the intersection data from the the parent via messaging.
123 A hypothetical host code:
125 ```javascript
126 function forwardIntersectionToIframe(iframe) {
127   createMessagingChannel(iframe, function(port) {
128     var io = new IntersectionObserver(function() {
129       port.postMessage({
130         boundingClientRect: serialize(boundingClientRect),
131         intersectionRect: serialize(intersectionRect)
132       });
133     }, {threshold: [0, 0.1, ..., 1]});
134     io.observe(iframe);
135   });
139 Notice that the host should provide a `threshold` argument for the desired
140 level of precision. Otherwise, the iframe side may not update as frequently as
141 desired.
143 A hypothetical iframe code:
145 ```javascript
146 createMessagingChannel(parent, function(port) {
147   if (IntersectionObserver._setupCrossOriginUpdater) {
148     var crossOriginUpdater = IntersectionObserver._setupCrossOriginUpdater();
149     port.onmessage = function(event) {
150       crossOriginUpdater(
151         deserialize(event.data.boundingClientRect),
152         deserialize(event.data.intersectionRect)
153       );
154     };
155   }
160 ## Limitations
162 This polyfill does not support the [proposed v2 additions](https://github.com/szager-chromium/IntersectionObserver/blob/v2/explainer.md), as these features are not currently possible to do with JavaScript and existing web APIs.
164 ## Browser support
166 The polyfill has been tested and known to work in the latest version of all browsers.
168 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](https://cdn.polyfill.io/v3/), which will automatically include dependencies where necessary:
170 ```html
171 <script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver"></script>
174 With these polyfills, `IntersectionObserver` has been tested an known to work in the following browsers:
176 <table>
177   <tr>
178     <td align="center">
179       <img src="https://raw.github.com/alrra/browser-logos/39.2.2/src/chrome/chrome_48x48.png" alt="Chrome"><br>
180       ✔
181     </td>
182     <td align="center">
183       <img src="https://raw.github.com/alrra/browser-logos/39.2.2/src/firefox/firefox_48x48.png" alt="Firefox"><br>
184       ✔
185     </td>
186     <td align="center">
187       <img src="https://raw.github.com/alrra/browser-logos/39.2.2/src/safari/safari_48x48.png" alt="Safari"><br>
188       6+
189     </td>
190     <td align="center">
191       <img src="https://raw.github.com/alrra/browser-logos/39.2.2/src/edge/edge_48x48.png" alt="Edge"><br>
192       ✔
193     </td>
194     <td align="center">
195       <img src="https://raw.github.com/alrra/browser-logos/39.2.2/src/archive/internet-explorer_7-8/internet-explorer_7-8_48x48.png" alt="Internet Explorer"><br>
196       7+
197     </td>
198     <td align="center">
199       <img src="https://raw.github.com/alrra/browser-logos/39.2.2/src/opera/opera_48x48.png" alt="Opera"><br>
200       ✔
201     </td>
202     <td align="center">
203       <img src="https://raw.github.com/alrra/browser-logos/39.2.2/src/android/android_48x48.png" alt="Android"><br>
204       4.4+
205     </td>
206   </tr>
207 </table>
209 ## Running the tests
211 To run the test suite for the `IntersectionObserver` polyfill, open the [`intersection-observer-test.html`](./intersection-observer-test.html) page in the browser of your choice.
213 If you run the tests in a browser that support `IntersectionObserver` natively, the tests will be run against the native implementation. If it doesn't the tests will be run against the polyfill.