Skip to content

Commit 5a11aad

Browse files
author
Oleg Korsunsky
committed
v 2.1.0
1 parent 6cc7913 commit 5a11aad

File tree

4 files changed

+82
-31
lines changed

4 files changed

+82
-31
lines changed

dist/stickyfill.es6.js

+35-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*!
22
* Stickyfill – `position: sticky` polyfill
3-
* v. 2.0.5 | https://github.com/wilddeer/stickyfill
3+
* v. 2.1.0 | https://github.com/wilddeer/stickyfill
44
* MIT License
55
*/
66

@@ -13,8 +13,10 @@
1313
*/
1414
let seppuku = false;
1515

16-
// The polyfill cant’t function properly without `getComputedStyle`.
17-
if (!window.getComputedStyle) seppuku = true;
16+
const isWindowDefined = typeof window !== 'undefined';
17+
18+
// The polyfill can’t function properly without `window` or `window.getComputedStyle`.
19+
if (!isWindowDefined || !window.getComputedStyle) seppuku = true;
1820
// Dont’t get in a way if the browser supports `position: sticky` natively.
1921
else {
2022
const testNode = document.createElement('div');
@@ -35,6 +37,7 @@ else {
3537
/*
3638
* 2. “Global” vars used across the polyfill
3739
*/
40+
let isInitialized = false;
3841

3942
// Check if Shadow Root constructor exists to make further checks simpler
4043
const shadowRootExists = typeof ShadowRoot !== 'undefined';
@@ -106,6 +109,7 @@ class Sticky {
106109
*/
107110
const nodeComputedStyle = getComputedStyle(node);
108111
const nodeComputedProps = {
112+
position: nodeComputedStyle.position,
109113
top: nodeComputedStyle.top,
110114
display: nodeComputedStyle.display,
111115
marginTop: nodeComputedStyle.marginTop,
@@ -127,7 +131,16 @@ class Sticky {
127131
this._active = true;
128132

129133
/*
130-
* 3. Get necessary node parameters
134+
* 3. Check if the current node position is `sticky`. If it is, it means that the browser supports sticky positioning,
135+
* but the polyfill was force-enabled. We set the node’s position to `static` before continuing, so that the node
136+
* is in it’s initial position when we gather its params.
137+
*/
138+
const originalPosition = node.style.position;
139+
if (nodeComputedStyle.position == 'sticky' || nodeComputedStyle.position == '-webkit-sticky')
140+
node.style.position = 'static';
141+
142+
/*
143+
* 4. Get necessary node parameters
131144
*/
132145
const referenceNode = node.parentNode;
133146
const parentNode = shadowRootExists && referenceNode instanceof ShadowRoot? referenceNode.host: referenceNode;
@@ -152,7 +165,7 @@ class Sticky {
152165
right: -nodeWinOffset.right + parentWinOffset.right - parseNumeric(parentComputedStyle.borderRightWidth)
153166
};
154167
this._styles = {
155-
position: node.style.position,
168+
position: originalPosition,
156169
top: node.style.top,
157170
bottom: node.style.bottom,
158171
left: node.style.left,
@@ -172,7 +185,7 @@ class Sticky {
172185
};
173186

174187
/*
175-
* 4. Ensure that the node will be positioned relatively to the parent node
188+
* 5. Ensure that the node will be positioned relatively to the parent node
176189
*/
177190
const parentPosition = parentComputedStyle.position;
178191

@@ -184,13 +197,13 @@ class Sticky {
184197
}
185198

186199
/*
187-
* 5. Recalc node position.
200+
* 6. Recalc node position.
188201
* It’s important to do this before clone injection to avoid scrolling bug in Chrome.
189202
*/
190203
this._recalcPosition();
191204

192205
/*
193-
* 6. Create a clone
206+
* 7. Create a clone
194207
*/
195208
const clone = this._clone = {};
196209
clone.node = document.createElement('div');
@@ -323,6 +336,13 @@ const Stickyfill = {
323336
stickies,
324337
Sticky,
325338

339+
forceSticky () {
340+
seppuku = false;
341+
init();
342+
343+
this.refreshAll();
344+
},
345+
326346
addOne (node) {
327347
// Check whether it’s a node
328348
if (!(node instanceof HTMLElement)) {
@@ -428,6 +448,12 @@ const Stickyfill = {
428448
* 6. Setup events (unless the polyfill was disabled)
429449
*/
430450
function init () {
451+
if (isInitialized) {
452+
return;
453+
}
454+
455+
isInitialized = true;
456+
431457
// Watch for scroll position changes and trigger recalc/refresh if needed
432458
function checkScroll () {
433459
if (window.pageXOffset != scroll.left) {
@@ -501,7 +527,7 @@ if (!seppuku) init();
501527
if (typeof module != 'undefined' && module.exports) {
502528
module.exports = Stickyfill;
503529
}
504-
else {
530+
else if (isWindowDefined) {
505531
window.Stickyfill = Stickyfill;
506532
}
507533

dist/stickyfill.js

+44-18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*!
22
* Stickyfill – `position: sticky` polyfill
3-
* v. 2.0.5 | https://github.com/wilddeer/stickyfill
3+
* v. 2.1.0 | https://github.com/wilddeer/stickyfill
44
* MIT License
55
*/
66

@@ -19,24 +19,29 @@
1919

2020
var seppuku = false;
2121

22-
// The polyfill cant’t function properly without `getComputedStyle`.
23-
if (!window.getComputedStyle) seppuku = true;
22+
var isWindowDefined = typeof window !== 'undefined';
23+
24+
// The polyfill can’t function properly without `window` or `window.getComputedStyle`.
25+
if (!isWindowDefined || !window.getComputedStyle) seppuku = true;
2426
// Dont’t get in a way if the browser supports `position: sticky` natively.
2527
else {
26-
var testNode = document.createElement('div');
28+
(function () {
29+
var testNode = document.createElement('div');
2730

28-
if (['', '-webkit-', '-moz-', '-ms-'].some(function (prefix) {
29-
try {
30-
testNode.style.position = prefix + 'sticky';
31-
} catch (e) {}
31+
if (['', '-webkit-', '-moz-', '-ms-'].some(function (prefix) {
32+
try {
33+
testNode.style.position = prefix + 'sticky';
34+
} catch (e) {}
3235

33-
return testNode.style.position != '';
34-
})) seppuku = true;
36+
return testNode.style.position != '';
37+
})) seppuku = true;
38+
})();
3539
}
3640

3741
/*
3842
* 2. “Global” vars used across the polyfill
3943
*/
44+
var isInitialized = false;
4045

4146
// Check if Shadow Root constructor exists to make further checks simpler
4247
var shadowRootExists = typeof ShadowRoot !== 'undefined';
@@ -111,6 +116,7 @@
111116
*/
112117
var nodeComputedStyle = getComputedStyle(node);
113118
var nodeComputedProps = {
119+
position: nodeComputedStyle.position,
114120
top: nodeComputedStyle.top,
115121
display: nodeComputedStyle.display,
116122
marginTop: nodeComputedStyle.marginTop,
@@ -128,7 +134,15 @@
128134
this._active = true;
129135

130136
/*
131-
* 3. Get necessary node parameters
137+
* 3. Check if the current node position is `sticky`. If it is, it means that the browser supports sticky positioning,
138+
* but the polyfill was force-enabled. We set the node’s position to `static` before continuing, so that the node
139+
* is in it’s initial position when we gather its params.
140+
*/
141+
var originalPosition = node.style.position;
142+
if (nodeComputedStyle.position == 'sticky' || nodeComputedStyle.position == '-webkit-sticky') node.style.position = 'static';
143+
144+
/*
145+
* 4. Get necessary node parameters
132146
*/
133147
var referenceNode = node.parentNode;
134148
var parentNode = shadowRootExists && referenceNode instanceof ShadowRoot ? referenceNode.host : referenceNode;
@@ -153,7 +167,7 @@
153167
right: -nodeWinOffset.right + parentWinOffset.right - parseNumeric(parentComputedStyle.borderRightWidth)
154168
};
155169
this._styles = {
156-
position: node.style.position,
170+
position: originalPosition,
157171
top: node.style.top,
158172
bottom: node.style.bottom,
159173
left: node.style.left,
@@ -171,7 +185,7 @@
171185
};
172186

173187
/*
174-
* 4. Ensure that the node will be positioned relatively to the parent node
188+
* 5. Ensure that the node will be positioned relatively to the parent node
175189
*/
176190
var parentPosition = parentComputedStyle.position;
177191

@@ -180,13 +194,13 @@
180194
}
181195

182196
/*
183-
* 5. Recalc node position.
197+
* 6. Recalc node position.
184198
* It’s important to do this before clone injection to avoid scrolling bug in Chrome.
185199
*/
186200
this._recalcPosition();
187201

188202
/*
189-
* 6. Create a clone
203+
* 7. Create a clone
190204
*/
191205
var clone = this._clone = {};
192206
clone.node = document.createElement('div');
@@ -330,6 +344,12 @@
330344
stickies: stickies,
331345
Sticky: Sticky,
332346

347+
forceSticky: function forceSticky() {
348+
seppuku = false;
349+
init();
350+
351+
this.refreshAll();
352+
},
333353
addOne: function addOne(node) {
334354
// Check whether it’s a node
335355
if (!(node instanceof HTMLElement)) {
@@ -380,9 +400,9 @@
380400
};
381401

382402
for (var i = 0; i < nodeList.length; i++) {
383-
var _ret = _loop(i);
403+
var _ret2 = _loop(i);
384404

385-
if (_ret === 'continue') continue;
405+
if (_ret2 === 'continue') continue;
386406
}
387407

388408
return addedStickies;
@@ -442,6 +462,12 @@
442462
* 6. Setup events (unless the polyfill was disabled)
443463
*/
444464
function init() {
465+
if (isInitialized) {
466+
return;
467+
}
468+
469+
isInitialized = true;
470+
445471
// Watch for scroll position changes and trigger recalc/refresh if needed
446472
function checkScroll() {
447473
if (window.pageXOffset != scroll.left) {
@@ -513,7 +539,7 @@
513539
*/
514540
if (typeof module != 'undefined' && module.exports) {
515541
module.exports = Stickyfill;
516-
} else {
542+
} else if (isWindowDefined) {
517543
window.Stickyfill = Stickyfill;
518544
}
519545

0 commit comments

Comments
 (0)