intersection-observer 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +14 -0
- package/border-test.html +47 -0
- package/frame1.html +9 -0
- package/frame2.html +9 -0
- package/frames.html +33 -0
- package/intersection-observer.js +7 -5
- package/package.json +1 -1
- package/slot.html +93 -0
package/README.md
CHANGED
@@ -81,6 +81,20 @@ io.observe(someTargetElement);
|
|
81
81
|
|
82
82
|
**Note:** the `POLL_INTERVAL` property must be set prior to calling the `.observe` method, or the default configuration will be used.
|
83
83
|
|
84
|
+
**Ignoring DOM changes**
|
85
|
+
|
86
|
+
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)
|
87
|
+
|
88
|
+
```js
|
89
|
+
IntersectionObserver.prototype.USE_MUTATION_OBSERVER = false; // Globally
|
90
|
+
|
91
|
+
// for an instance
|
92
|
+
var io = new IntersectionObserver(callback);
|
93
|
+
io.USE_MUTATION_OBSERVER = false;
|
94
|
+
```
|
95
|
+
|
96
|
+
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.
|
97
|
+
|
84
98
|
## Browser support
|
85
99
|
|
86
100
|
The polyfill has been tested and known to work in the latest version of all browsers.
|
package/border-test.html
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<script>
|
6
|
+
// delete window.IntersectionObserver;
|
7
|
+
</script>
|
8
|
+
<script src="intersection-observer.js"></script>
|
9
|
+
<script>
|
10
|
+
function init() {
|
11
|
+
function callback(entries, observer) {
|
12
|
+
Array.prototype.forEach.call(entries, function(entry) {
|
13
|
+
if (entry.intersectionRatio > 0) {
|
14
|
+
entry.target.classList.add('visible');
|
15
|
+
}
|
16
|
+
});
|
17
|
+
}
|
18
|
+
var observer = new IntersectionObserver(callback, { root: document.getElementById('outer') });
|
19
|
+
Array.prototype.forEach.call(document.querySelectorAll('#outer div'), function(el) {
|
20
|
+
observer.observe(el);
|
21
|
+
});
|
22
|
+
}
|
23
|
+
window.addEventListener('load', init);
|
24
|
+
</script>
|
25
|
+
<style>
|
26
|
+
#outer {
|
27
|
+
overflow-y: hidden;
|
28
|
+
height: 2em;
|
29
|
+
border: 10px solid #0000;
|
30
|
+
}
|
31
|
+
#outer div {
|
32
|
+
height: 100%;
|
33
|
+
}
|
34
|
+
#el2 {
|
35
|
+
background: red;
|
36
|
+
}
|
37
|
+
|
38
|
+
</style>
|
39
|
+
</head>
|
40
|
+
<body>
|
41
|
+
<div id="outer">
|
42
|
+
<div id="el1">Element 1</div>
|
43
|
+
<div id="el2">Element 2</div>
|
44
|
+
<div id="el3">Element 3</div>
|
45
|
+
</div>
|
46
|
+
</body>
|
47
|
+
</html>
|
package/frame1.html
ADDED
package/frame2.html
ADDED
package/frames.html
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
<!--
|
2
|
+
Copyright 2016 Google Inc. All Rights Reserved.
|
3
|
+
|
4
|
+
Licensed under the W3C SOFTWARE AND DOCUMENT NOTICE AND LICENSE.
|
5
|
+
|
6
|
+
https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
7
|
+
-->
|
8
|
+
<!DOCTYPE html>
|
9
|
+
<html lang="en">
|
10
|
+
<head>
|
11
|
+
<meta charset="utf-8">
|
12
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
13
|
+
<title>IntersectionObserver Tests</title>
|
14
|
+
|
15
|
+
<!-- Dependencies -->
|
16
|
+
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.5.3/mocha.min.css">
|
17
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.5.3/mocha.min.js"></script>
|
18
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/expect.js/0.2.0/expect.min.js"></script>
|
19
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/3.2.1/sinon.min.js"></script>
|
20
|
+
|
21
|
+
-->
|
22
|
+
|
23
|
+
<styles>
|
24
|
+
|
25
|
+
</styles>
|
26
|
+
</head>
|
27
|
+
<body>
|
28
|
+
|
29
|
+
<iframe src="frame1.html"></iframe>
|
30
|
+
<iframe src="frame2.html"></iframe>
|
31
|
+
|
32
|
+
</body>
|
33
|
+
</html>
|
package/intersection-observer.js
CHANGED
@@ -33,7 +33,7 @@ if ('IntersectionObserver' in window &&
|
|
33
33
|
|
34
34
|
/**
|
35
35
|
* An IntersectionObserver registry. This registry exists to hold a strong
|
36
|
-
* reference to IntersectionObserver instances currently
|
36
|
+
* reference to IntersectionObserver instances currently observing a target
|
37
37
|
* element. Without this registry, instances without another reference may be
|
38
38
|
* garbage collected.
|
39
39
|
*/
|
@@ -62,7 +62,9 @@ function IntersectionObserverEntry(entry) {
|
|
62
62
|
|
63
63
|
// Sets intersection ratio.
|
64
64
|
if (targetArea) {
|
65
|
-
|
65
|
+
// Round the intersection ratio to avoid floating point math issues:
|
66
|
+
// https://github.com/w3c/IntersectionObserver/issues/324
|
67
|
+
this.intersectionRatio = Number((intersectionArea / targetArea).toFixed(4));
|
66
68
|
} else {
|
67
69
|
// If area is zero and is intersecting, sets to 1, otherwise to 0
|
68
70
|
this.intersectionRatio = this.isIntersecting ? 1 : 0;
|
@@ -250,7 +252,7 @@ IntersectionObserver.prototype._parseRootMargin = function(opt_rootMargin) {
|
|
250
252
|
|
251
253
|
/**
|
252
254
|
* Starts polling for intersection changes if the polling is not already
|
253
|
-
* happening, and if the page's
|
255
|
+
* happening, and if the page's visibility state is visible.
|
254
256
|
* @private
|
255
257
|
*/
|
256
258
|
IntersectionObserver.prototype._monitorIntersections = function() {
|
@@ -552,7 +554,7 @@ function now() {
|
|
552
554
|
|
553
555
|
|
554
556
|
/**
|
555
|
-
* Throttles a function and delays its
|
557
|
+
* Throttles a function and delays its execution, so it's only called at most
|
556
558
|
* once within a given time period.
|
557
559
|
* @param {Function} fn The function to throttle.
|
558
560
|
* @param {number} timeout The amount of time that must pass before the
|
@@ -683,7 +685,7 @@ function getEmptyRect() {
|
|
683
685
|
}
|
684
686
|
|
685
687
|
/**
|
686
|
-
* Checks to see if a parent element contains a child
|
688
|
+
* Checks to see if a parent element contains a child element (including inside
|
687
689
|
* shadow DOM).
|
688
690
|
* @param {Node} parent The parent element.
|
689
691
|
* @param {Node} child The child element.
|
package/package.json
CHANGED
package/slot.html
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
<template id="slot-test">
|
2
|
+
<style>
|
3
|
+
|
4
|
+
</style>
|
5
|
+
<div>
|
6
|
+
<h3>Title</h3>
|
7
|
+
<aside>
|
8
|
+
<slot name="contents"></slot>
|
9
|
+
</aside>
|
10
|
+
</div>
|
11
|
+
</template>
|
12
|
+
|
13
|
+
|
14
|
+
<my-el>
|
15
|
+
<ul slot="contents">
|
16
|
+
<li>one</li>
|
17
|
+
<li>two</li>
|
18
|
+
<li>three</li>
|
19
|
+
</ul>
|
20
|
+
<ul slot="contents">
|
21
|
+
<li>four</li>
|
22
|
+
<li>five</li>
|
23
|
+
<li>six</li>
|
24
|
+
</ul>
|
25
|
+
</my-el>
|
26
|
+
|
27
|
+
|
28
|
+
<script>
|
29
|
+
class MyEl extends HTMLElement {
|
30
|
+
constructor() {
|
31
|
+
super();
|
32
|
+
|
33
|
+
const shadowRoot = this.attachShadow({mode: 'open'});
|
34
|
+
shadowRoot.innerHTML = `
|
35
|
+
<style>
|
36
|
+
|
37
|
+
</style>
|
38
|
+
<div>
|
39
|
+
<h3>Title</h3>
|
40
|
+
<aside>
|
41
|
+
<slot name="contents"></slot>
|
42
|
+
</aside>
|
43
|
+
</div>
|
44
|
+
`;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
self.customElements.define('my-el', MyEl);
|
49
|
+
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Checks to see if a parent element contains a child elemnt (including inside
|
53
|
+
* shadow DOM).
|
54
|
+
* @param {Node} parent The parent element.
|
55
|
+
* @param {Node} child The child element.
|
56
|
+
* @return {boolean} True if the parent node contains the child node.
|
57
|
+
*/
|
58
|
+
function containsDeep(parent, child) {
|
59
|
+
var node = child;
|
60
|
+
while (node) {
|
61
|
+
if (node == parent) return true;
|
62
|
+
|
63
|
+
node = getParentNode(node);
|
64
|
+
}
|
65
|
+
return false;
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Gets the parent node of an element or its host element if the parent node
|
71
|
+
* is a shadow root.
|
72
|
+
* @param {Node} node The node whose parent to get.
|
73
|
+
* @return {Node|null} The parent node or null if no parent exists.
|
74
|
+
*/
|
75
|
+
function getParentNode(node) {
|
76
|
+
var parent = node.parentNode;
|
77
|
+
|
78
|
+
if (parent) {
|
79
|
+
if (parent.nodeType == 11 && parent.host) {
|
80
|
+
// If the parent is a shadow root, return the host element.
|
81
|
+
return parent.host;
|
82
|
+
}
|
83
|
+
|
84
|
+
if (parent.assignedSlot) {
|
85
|
+
// If the parent is assigned a slot, return the slot's parent.
|
86
|
+
return parent.assignedSlot.parentNode;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
return parent;
|
90
|
+
}
|
91
|
+
|
92
|
+
|
93
|
+
</script>
|