@@ -170,7 +170,7 @@ function getViewportCollisions(coords, elementWidth, elementHeight) {
170
170
// adjusting viewport even though it might be negative because coords
171
171
// comparing with are relative to compensated position
172
172
var viewportTop = session . scrollTop - session . positionCompensation . top ,
173
- viewportLeft = session . scrollLeft - session . positionCompensation . left ,
173
+ viewportLeft = session . scrollLeft - session . positionCompensation . left ,
174
174
viewportBottom = viewportTop + session . windowHeight ,
175
175
viewportRight = viewportLeft + session . windowWidth ,
176
176
collisions = Collision . none ;
@@ -206,38 +206,51 @@ function countFlags(value) {
206
206
}
207
207
208
208
/**
209
- * Compute compensating position offsets if body element has non-standard position attribute.
209
+ * Compute compensating position offsets if body or html element has non-static position attribute.
210
210
* @private
211
211
* @param {number } windowWidth Window width in pixels.
212
212
* @param {number } windowHeight Window height in pixels.
213
213
* @return {Offsets } The top, left, right, bottom offset in pixels
214
214
*/
215
215
function computePositionCompensation ( windowWidth , windowHeight ) {
216
- var bodyWidthWithMargin ,
217
- bodyHeightWithMargin ,
218
- offsets ,
219
- bodyPositionPx ;
220
-
221
- switch ( $body . css ( 'position' ) ) {
222
- case 'absolute' :
223
- case 'fixed' :
224
- case 'relative' :
225
- // jquery offset and position functions return top and left
226
- // offset function computes position + margin
227
- offsets = $body . offset ( ) ;
228
- bodyPositionPx = $body . position ( ) ;
229
- // because element might be positioned compute right margin using the different between
230
- // outerWidth computations and add position offset
231
- bodyWidthWithMargin = $body . outerWidth ( true ) ;
232
- bodyHeightWithMargin = $body . outerHeight ( true ) ;
233
- // right offset = right margin + body right position
234
- offsets . right = ( bodyWidthWithMargin - $body . outerWidth ( ) - ( offsets . left - bodyPositionPx . left ) ) + ( windowWidth - bodyWidthWithMargin - bodyPositionPx . left ) ;
235
- // bottom offset = bottom margin + body bottom position
236
- offsets . bottom = ( bodyHeightWithMargin - $body . outerHeight ( ) - offsets . top ) + ( windowHeight - bodyHeightWithMargin - bodyPositionPx . top ) ;
237
- break ;
238
- default :
239
- // even though body may have offset, no compensation is required
240
- offsets = { top : 0 , bottom : 0 , left : 0 , right : 0 } ;
216
+ // Check if the element is "positioned". A "positioned" element has a CSS
217
+ // position value other than static. Whether the element is positioned is
218
+ // relevant because absolutely positioned elements are positioned relative
219
+ // to the first positioned ancestor rather than relative to the doc origin.
220
+ var isPositioned = function ( el ) {
221
+ return el . css ( 'position' ) !== 'static' ;
222
+ } ;
223
+
224
+ var getViewportToElementOffset = function ( el ) {
225
+ var elWidthWithMargin ,
226
+ elHeightWithMargin ,
227
+ elPositionPx ,
228
+ offsets ;
229
+ // jquery offset and position functions return top and left
230
+ // offset function computes position + margin
231
+ offsets = el . offset ( ) ;
232
+ elPositionPx = el . position ( ) ;
233
+
234
+ // Compute the far margins based off the outerWidth values.
235
+ elWidthWithMargin = el . outerWidth ( true ) ;
236
+ elHeightWithMargin = el . outerHeight ( true ) ;
237
+
238
+ // right offset = right margin + body right position
239
+ offsets . right = ( elWidthWithMargin - el . outerWidth ( ) - ( offsets . left - elPositionPx . left ) ) + ( windowWidth - elWidthWithMargin - elPositionPx . left ) ;
240
+ // bottom offset = bottom margin + body bottom position
241
+ offsets . bottom = ( elHeightWithMargin - el . outerHeight ( ) - offsets . top ) + ( windowHeight - elHeightWithMargin - elPositionPx . top ) ;
242
+ return offsets ;
243
+ } ;
244
+
245
+ var offsets ;
246
+
247
+ if ( isPositioned ( $body ) ) {
248
+ offsets = getViewportToElementOffset ( $body ) ;
249
+ } else if ( isPositioned ( $html ) ) {
250
+ offsets = getViewportToElementOffset ( $html ) ;
251
+ } else {
252
+ // even though body may have offset, no compensation is required
253
+ offsets = { top : 0 , bottom : 0 , left : 0 , right : 0 } ;
241
254
}
242
255
243
256
return offsets ;
0 commit comments