1
1
/*!
2
2
* Stickyfill – `position: sticky` polyfill
3
- * v. 2.0.5 | https://github.com/wilddeer/stickyfill
3
+ * v. 2.1.0 | https://github.com/wilddeer/stickyfill
4
4
* MIT License
5
5
*/
6
6
13
13
*/
14
14
let seppuku = false ;
15
15
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 ;
18
20
// Dont’t get in a way if the browser supports `position: sticky` natively.
19
21
else {
20
22
const testNode = document . createElement ( 'div' ) ;
35
37
/*
36
38
* 2. “Global” vars used across the polyfill
37
39
*/
40
+ let isInitialized = false ;
38
41
39
42
// Check if Shadow Root constructor exists to make further checks simpler
40
43
const shadowRootExists = typeof ShadowRoot !== 'undefined' ;
@@ -106,6 +109,7 @@ class Sticky {
106
109
*/
107
110
const nodeComputedStyle = getComputedStyle ( node ) ;
108
111
const nodeComputedProps = {
112
+ position : nodeComputedStyle . position ,
109
113
top : nodeComputedStyle . top ,
110
114
display : nodeComputedStyle . display ,
111
115
marginTop : nodeComputedStyle . marginTop ,
@@ -127,7 +131,16 @@ class Sticky {
127
131
this . _active = true ;
128
132
129
133
/*
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
131
144
*/
132
145
const referenceNode = node . parentNode ;
133
146
const parentNode = shadowRootExists && referenceNode instanceof ShadowRoot ? referenceNode . host : referenceNode ;
@@ -152,7 +165,7 @@ class Sticky {
152
165
right : - nodeWinOffset . right + parentWinOffset . right - parseNumeric ( parentComputedStyle . borderRightWidth )
153
166
} ;
154
167
this . _styles = {
155
- position : node . style . position ,
168
+ position : originalPosition ,
156
169
top : node . style . top ,
157
170
bottom : node . style . bottom ,
158
171
left : node . style . left ,
@@ -172,7 +185,7 @@ class Sticky {
172
185
} ;
173
186
174
187
/*
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
176
189
*/
177
190
const parentPosition = parentComputedStyle . position ;
178
191
@@ -184,13 +197,13 @@ class Sticky {
184
197
}
185
198
186
199
/*
187
- * 5 . Recalc node position.
200
+ * 6 . Recalc node position.
188
201
* It’s important to do this before clone injection to avoid scrolling bug in Chrome.
189
202
*/
190
203
this . _recalcPosition ( ) ;
191
204
192
205
/*
193
- * 6 . Create a clone
206
+ * 7 . Create a clone
194
207
*/
195
208
const clone = this . _clone = { } ;
196
209
clone . node = document . createElement ( 'div' ) ;
@@ -323,6 +336,13 @@ const Stickyfill = {
323
336
stickies,
324
337
Sticky,
325
338
339
+ forceSticky ( ) {
340
+ seppuku = false ;
341
+ init ( ) ;
342
+
343
+ this . refreshAll ( ) ;
344
+ } ,
345
+
326
346
addOne ( node ) {
327
347
// Check whether it’s a node
328
348
if ( ! ( node instanceof HTMLElement ) ) {
@@ -428,6 +448,12 @@ const Stickyfill = {
428
448
* 6. Setup events (unless the polyfill was disabled)
429
449
*/
430
450
function init ( ) {
451
+ if ( isInitialized ) {
452
+ return ;
453
+ }
454
+
455
+ isInitialized = true ;
456
+
431
457
// Watch for scroll position changes and trigger recalc/refresh if needed
432
458
function checkScroll ( ) {
433
459
if ( window . pageXOffset != scroll . left ) {
@@ -501,7 +527,7 @@ if (!seppuku) init();
501
527
if ( typeof module != 'undefined' && module . exports ) {
502
528
module . exports = Stickyfill ;
503
529
}
504
- else {
530
+ else if ( isWindowDefined ) {
505
531
window . Stickyfill = Stickyfill ;
506
532
}
507
533
0 commit comments