intersection-observer 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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>
|