Parent scroll isn't disabled when scrolling on touch device.
I tested this with iPad 2 and iPhone 6 and the actual demo (release 0.9.7).
+1
Problem still exists in v. 0.10.0.
Possible Fix:
body.md-dialog-is-showing {
position: fixed;
width: 100%;
}
Unfortunately, this way, the page scrolls to the top as soon as md-dialog-is-showing is added to the dom. So to avoid that, you can put your body in a fixed position and the main content in a scrollable md-content:
body {
position: fixed;
top:0;
left:0;
right: 0;
bottom: 0;
width: 100%;
overflow: hidden;
}
md-content.main-scrollable {
position: absolute;
left:0;
top: 58px;
right: 0;
bottom: 0;
overflow-y: scroll;
}
note: the top: 58pxcss is for the top bar, so the value may differ depeding on your top bar height.
note2: tried a solution with javascript scrolling-events first, but that unfortunately results in a slow browser experience. But more importantly, it seems like you can't really stop safari from scrolling (there seem to be two different scrolling modes, one for the tapped element and one for the body. The last one seems gives me the wrong target in javascript (it's always the element), so i don't know how to decide whats actually being scrolled). Only solution would be to disable the scrolling entirely, which is not really an option on a mobile device.
Not sure if this is the right solution for the problem but this actually fixed the issue for me on iPhone-6
.md-dialog-container{
position: fixed;
top: 0 !important;
height: 100%;
}
.md-dialog-container md-dialog{
max-height: 100%;
}
+1. With successful javascript workaround.
Issue occurs in any iOS webview based container (Chrome on iOS, Cordova App on iOS). Not tested on Android.
Debugging (briefly) led to the the disableParentScroll feature. Noticed it is being applied to a <div> that is a sibling, and not a direct parent of the dialog. But rather than try to wrangle with all the implications of a deeper investigation of that, opted for the following javascript workaround...
disableParentScroll false on invocation...$mdDialog.show({
templateUrl: 'views/my-dialog.html',
disableParentScroll: false
});
views/my-dialog.html...<md-dialog my-workaround>
.
.
.
</md-dialog>
my-workaround directive, invoke a touchmove handler to achieve desired functionality...jQuery is loaded, but could be rewritten without it of course).angular.module('myApp')
.directive('myWorkaround',
function ($timeout, $mdDialog) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
$.fn.isVScrollable = function () {
return this[0].scrollHeight > this[0].clientHeight;
};
var dialogContent = $(element).find('md-dialog-content');
var touchFix = function(evt) {
if ($(evt.target).hasClass('md-dialog-container') || ! dialogContent.isVScrollable()) {
// preventDefault when gesture occurred inside the container OR my dialog does not scroll.
evt.preventDefault();
} else {
// consume gesture when it occurs inside my (scrollable) dialog.
evt.stopPropagation();
}
};
$timeout(function() {
// Mobile gesture(s) patch. Prevent iOS scroll of elements underneath the dialog...
$('.md-dialog-container').on('touchmove', touchFix);
element.on('$destroy', function () {
$('.md-dialog-container').off('touchmove', touchFix);
});
});
}
};
});
+1 on this one
This issue still exist in my iPhone 5S (iOS 9.3.1). I have tested with v1.0.8 demo page.
Why this issue marked as deprecated?
Directive works well for custom dialogs, any possible solution for alert or confirm dialogs?
How jjf1's code as an angular config would look like:
/**
* md-dialog config
*/
MdDialogConfig.$inject = [
"$provide"
];
function MdDialogConfig($provide: ng.auto.IProvideService) {
$provide.decorator("$mdDialog", ["$delegate", "$timeout", ($delegate, $timeout) => {
let show = $delegate.show;
$delegate.show = function extend(tElement) {
show.apply(this, arguments);
let dialogContent;
let dialogContainer;
console.log(tElement);
let touchFix = function(event) {
let target = event.target;
// console.log(target);
// console.log(dialogContent.contains(target));
if (!dialogContent.contains(target)) {
// preventDefault when gesture occurred outside the dialog
event.preventDefault();
} else {
// consume gesture when it occurs inside the dialog
event.stopPropagation();
}
};
$timeout(() => {
dialogContainer = document.getElementsByClassName("md-dialog-container")[0];
dialogContent = document.getElementsByTagName("md-dialog")[0];
// console.log(dialogContainer);
// console.log(dialogContent);
dialogContainer.addEventListener("touchmove", touchFix);
});
};
return $delegate;
}]);
}
export default MdDialogConfig;
But if you just want to disable the scroll of the parent element just add css style to it. In our project we have a md-content container below our header in which every view is loaded. The container got an id, so our css looks like this:
body.md-dialog-is-showing #md-content-id {
overflow: hidden;
}
Most helpful comment
Not sure if this is the right solution for the problem but this actually fixed the issue for me on iPhone-6
.md-dialog-container{
position: fixed;
top: 0 !important;
height: 100%;
}
.md-dialog-container md-dialog{
max-height: 100%;
}