Forward Compatibility w/ WebKit & Blink

Newer versions of WebKit and Blink will support both `document.body.scrollTop` and `document.documentElement.scrollTop`. Therefore, implementing cross-browser compatibility by summing the two will no longer work.

This changes React to use `getUnboundedScrollPosition` so we get the fix and consistency in one change!

See: https://rniwa.com/2013-10-29/web-compatibility-story-of-scrolltop-and-scrollleft/
This commit is contained in:
Tim Yung
2013-12-12 15:56:59 -08:00
committed by Paul O’Shannessy
parent 48af9c7bda
commit 7ecd72e724
3 changed files with 62 additions and 4 deletions
+5 -4
View File
@@ -18,6 +18,8 @@
"use strict";
var getUnboundedScrollPosition = require('getUnboundedScrollPosition');
var ViewportMetrics = {
currentScrollLeft: 0,
@@ -25,10 +27,9 @@ var ViewportMetrics = {
currentScrollTop: 0,
refreshScrollValues: function() {
ViewportMetrics.currentScrollLeft =
document.body.scrollLeft + document.documentElement.scrollLeft;
ViewportMetrics.currentScrollTop =
document.body.scrollTop + document.documentElement.scrollTop;
var scrollPosition = getUnboundedScrollPosition(window);
ViewportMetrics.currentScrollLeft = scrollPosition.x;
ViewportMetrics.currentScrollTop = scrollPosition.y;
}
};
+27
View File
@@ -0,0 +1,27 @@
/**
* @providesModule getDocumentScrollElement
* @typechecks
*/
"use strict";
// TODO: Replace this with a UserAgent module.
var isWebkit = navigator.userAgent.indexOf('AppleWebKit') > -1;
/**
* Gets the element with the document scroll properties such as `scrollLeft` and
* `scrollHeight`. This may differ across different browsers.
*
* NOTE: The return value can be null if the DOM is not yet ready.
*
* @param {?DOMDocument} doc Defaults to current document.
* @return {?DOMElement}
*/
function getDocumentScrollElement(doc) {
doc = doc || document;
return !isWebkit && doc.compatMode === 'CSS1Compat' ?
doc.documentElement :
doc.body;
}
module.exports = getDocumentScrollElement;
+30
View File
@@ -0,0 +1,30 @@
/**
* @providesModule getUnboundedScrollPosition
* @typechecks
*/
"use strict";
var getDocumentScrollElement = require('getDocumentScrollElement');
/**
* Gets the scroll position of the supplied element or window.
*
* The return values are unbounded, unlike `getScrollPosition`. This means they
* may be negative or exceed the element boundaries (which is possible using
* inertial scrolling).
*
* @param {DOMWindow|DOMElement} scrollable
* @return {object} Map with `x` and `y` keys.
*/
function getUnboundedScrollPosition(scrollable) {
if (scrollable === window) {
return getUnboundedScrollPosition(getDocumentScrollElement());
}
return {
x: scrollable.scrollLeft,
y: scrollable.scrollTop
};
}
module.exports = getUnboundedScrollPosition;