Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 4468126

Browse files
crisbetojelbourn
authored andcommitted
fix(util): body overflow-x breaking disableScrollAround (#9864)
Currently the `disableScrollAround` function measures the body in order to determine whether to hide it's overflow. This measurement can get thrown off by the `html` node's scrollbar that gets added a few lines above. This change switches to adding the scrollbar to the `html` node after the body measurements are done. Fixes #9860.
1 parent 97cbe69 commit 4468126

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

src/core/util/util.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -283,22 +283,27 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
283283

284284
var viewportTop = $mdUtil.getViewportTop();
285285
var clientWidth = body.clientWidth;
286+
var hasVerticalScrollbar = body.scrollHeight > body.clientHeight + 1;
286287

287-
if (body.scrollHeight > body.clientHeight + 1) {
288-
288+
if (hasVerticalScrollbar) {
289289
angular.element(body).css({
290290
position: 'fixed',
291291
width: '100%',
292292
top: -viewportTop + 'px'
293293
});
294-
295-
documentElement.style.overflowY = 'scroll';
296294
}
297295

298296
if (body.clientWidth < clientWidth) {
299297
body.style.overflow = 'hidden';
300298
}
301299

300+
// This should be applied after the manipulation to the body, because
301+
// adding a scrollbar can potentially resize it, causing the measurement
302+
// to change.
303+
if (hasVerticalScrollbar) {
304+
documentElement.style.overflowY = 'scroll';
305+
}
306+
302307
return function restoreScroll() {
303308
// Reset the inline style CSS to the previous.
304309
body.style.cssText = prevBodyStyle;

src/core/util/util.spec.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ describe('util', function() {
9898
};
9999

100100
expect(function() {
101-
$mdUtil.getModelOption(ngModelCtrl, 'Unknown')
101+
$mdUtil.getModelOption(ngModelCtrl, 'Unknown');
102102
}).not.toThrow();
103103
}));
104104

@@ -268,7 +268,7 @@ describe('util', function() {
268268
element.remove();
269269
}));
270270

271-
it('should not remove the element when being use as scorll mask', inject(function($mdUtil) {
271+
it('should not remove the element when being use as scroll mask', inject(function($mdUtil) {
272272
var element = angular.element('<div>');
273273

274274
document.body.appendChild(element[0]);
@@ -285,6 +285,27 @@ describe('util', function() {
285285
element.remove();
286286
}));
287287

288+
it('should not get thrown off by the scrollbar on the <html> node',
289+
inject(function($mdUtil) {
290+
var element = angular.element('<div style="height: 2000px">');
291+
292+
document.body.appendChild(element[0]);
293+
document.body.style.overflowX = 'hidden';
294+
295+
window.scrollTo(0, 1000);
296+
297+
var enableScrolling = $mdUtil.disableScrollAround(element);
298+
299+
expect(document.body.style.overflow).not.toBe('hidden');
300+
301+
// Restore the scrolling.
302+
enableScrolling();
303+
window.scrollTo(0, 0);
304+
document.body.style.overflowX = '';
305+
306+
element.remove();
307+
})
308+
);
288309
});
289310

290311
describe('getViewportTop', function() {

0 commit comments

Comments
 (0)