-
Notifications
You must be signed in to change notification settings - Fork 3.4k
dialog: iOS fixed position bug causes dialog to appear off screen #10675
Description
Actual Behavior:
-
On actual iOs Devices when opening a dialog into a fixed container sometimes the
stretchDialogContainerToViewport
function's 'getBoundingClientRect()' returns the windows scroll location instead of 0. This causes the dialog to appear off screen and become un-closeable. Issue stems from a known iOS bug since iOS8 where fixed elements return an improper location while scrolling & the act of clicking inside the touch interface can sometimes cause a scroll. See this for an explination of the behavior: open radar -
mdDialog opening to fixed position should always have a top position of 0 or the top position of the fixed container.
CodePen (or steps to reproduce the issue): *
- http://codepen.io/8bit_tom/pen/mmzYpw
- Happens intermittently as it requires a scroll. Happens 80-90% of the time in my app though.
AngularJS Versions: *
- Angular: 1.6.4
- Material: 1.1.4
Additional Information:
Browser Type: *
Mobile SafariBrowser Version: *
8+OS: *
iOS 8+Stack Traces:
Proposed Solution
Listen for scroll and debounce stretchDialogContainerToViewport() function (angular material.js line: 10649, dialog.js line: 1173) In my project wrapping the function in a simple 100ms timeout solves the problem 90% of the time
function stretchDialogContainerToViewport(container, options) {
setTimeout(function(){ //short debounce for ios fixed position while scrolling issue
var isFixed = $window.getComputedStyle($document[0].body).position == 'fixed';
var backdrop = options.backdrop ? $window.getComputedStyle(options.backdrop[0]) : null;
var height = backdrop ? Math.min($document[0].body.clientHeight, Math.ceil(Math.abs(parseInt(backdrop.height, 10)))) : 0;
var previousStyles = {
top: container.css('top'),
height: container.css('height')
};
// If the body is fixed, determine the distance to the viewport in relative from the parent.
var parentTop = Math.abs(options.parent[0].getBoundingClientRect().top);
container.css({
top: (isFixed ? parentTop : 0) + 'px',
height: height ? height + 'px' : '100%'
});
return function () {
// Reverts the modified styles back to the previous values.
// This is needed for contentElements, which should have the same styles after close
// as before.
container.css(previousStyles);
};
}, 100);
};