fix: body scroll when open modal #1472
parent
c86a261bca
commit
e4f83939b9
|
@ -4,7 +4,7 @@ exports[`Modal render correctly 1`] = `
|
|||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<div class="ant-modal-root">
|
||||
<div class="ant-modal-mask"></div>
|
||||
<div tabindex="-1" role="dialog" class="ant-modal-wrap ">
|
||||
<div role="document" class="ant-modal" style="width: 520px;">
|
||||
|
@ -29,7 +29,7 @@ exports[`Modal render correctly 2`] = `
|
|||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<div class="ant-modal-root">
|
||||
<div class="ant-modal-mask"></div>
|
||||
<div tabindex="-1" role="dialog" class="ant-modal-wrap ">
|
||||
<div role="document" class="ant-modal" style="width: 520px;">
|
||||
|
@ -54,7 +54,7 @@ exports[`Modal render without footer 1`] = `
|
|||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<div class="ant-modal-root">
|
||||
<div class="ant-modal-mask"></div>
|
||||
<div tabindex="-1" role="dialog" class="ant-modal-wrap ">
|
||||
<div role="document" class="ant-modal" style="width: 520px;">
|
||||
|
|
|
@ -46,6 +46,8 @@ function offset(el) {
|
|||
return pos;
|
||||
}
|
||||
|
||||
let cacheOverflow = {};
|
||||
|
||||
export default {
|
||||
mixins: [BaseMixin],
|
||||
props: initDefaultProps(IDialogPropTypes, {
|
||||
|
@ -57,6 +59,7 @@ export default {
|
|||
destroyOnClose: false,
|
||||
prefixCls: 'rc-dialog',
|
||||
getOpenCount: () => null,
|
||||
focusTriggerAfterClose: true,
|
||||
}),
|
||||
data() {
|
||||
return {
|
||||
|
@ -81,16 +84,6 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
// private inTransition: boolean;
|
||||
// private titleId: string;
|
||||
// private openTime: number;
|
||||
// private lastOutSideFocusNode: HTMLElement | null;
|
||||
// private wrap: HTMLElement;
|
||||
// private dialog: any;
|
||||
// private sentinel: HTMLElement;
|
||||
// private bodyIsOverflowing: boolean;
|
||||
// private scrollbarWidth: number;
|
||||
|
||||
beforeMount() {
|
||||
this.inTransition = false;
|
||||
this.titleId = `rcDialogTitle${uuid++}`;
|
||||
|
@ -107,7 +100,7 @@ export default {
|
|||
beforeDestroy() {
|
||||
const { visible, getOpenCount } = this;
|
||||
if ((visible || this.inTransition) && !getOpenCount()) {
|
||||
this.removeScrollingEffect();
|
||||
this.switchScrollingEffect();
|
||||
}
|
||||
clearTimeout(this.timeoutId);
|
||||
},
|
||||
|
@ -118,12 +111,13 @@ export default {
|
|||
},
|
||||
updatedCallback(visible) {
|
||||
const mousePosition = this.mousePosition;
|
||||
const {mask, focusTriggerAfterClose} = this;
|
||||
if (this.visible) {
|
||||
// first show
|
||||
if (!visible) {
|
||||
this.openTime = Date.now();
|
||||
// this.lastOutSideFocusNode = document.activeElement
|
||||
this.addScrollingEffect();
|
||||
this.switchScrollingEffect();
|
||||
// this.$refs.wrap.focus()
|
||||
this.tryFocus();
|
||||
const dialogNode = this.$refs.dialog.$el;
|
||||
|
@ -139,7 +133,7 @@ export default {
|
|||
}
|
||||
} else if (visible) {
|
||||
this.inTransition = true;
|
||||
if (this.mask && this.lastOutSideFocusNode) {
|
||||
if (mask && this.lastOutSideFocusNode && focusTriggerAfterClose) {
|
||||
try {
|
||||
this.lastOutSideFocusNode.focus();
|
||||
} catch (e) {
|
||||
|
@ -166,7 +160,7 @@ export default {
|
|||
this.destroyPopup = true;
|
||||
}
|
||||
this.inTransition = false;
|
||||
this.removeScrollingEffect();
|
||||
this.switchScrollingEffect();
|
||||
if (afterClose) {
|
||||
afterClose();
|
||||
}
|
||||
|
@ -224,6 +218,7 @@ export default {
|
|||
bodyStyle,
|
||||
visible,
|
||||
bodyProps,
|
||||
forceRender,
|
||||
} = this;
|
||||
const dest = {};
|
||||
if (width !== undefined) {
|
||||
|
@ -284,6 +279,7 @@ export default {
|
|||
ref="dialog"
|
||||
style={style}
|
||||
class={cls}
|
||||
forceRender={forceRender}
|
||||
onMousedown={this.onDialogMouseDown}
|
||||
>
|
||||
<div tabIndex={0} ref="sentinelStart" style={sentinelStyle} aria-hidden="true" />
|
||||
|
@ -369,60 +365,50 @@ export default {
|
|||
// document.body.style.paddingRight = `${this.scrollbarWidth}px`;
|
||||
// }
|
||||
// },
|
||||
addScrollingEffect() {
|
||||
switchScrollingEffect() {
|
||||
const { getOpenCount } = this;
|
||||
const openCount = getOpenCount();
|
||||
if (openCount !== 1) {
|
||||
return;
|
||||
if (openCount === 1) {
|
||||
if (cacheOverflow.hasOwnProperty('overflowX')) {
|
||||
return;
|
||||
}
|
||||
cacheOverflow = {
|
||||
overflowX: document.body.style.overflowX,
|
||||
overflowY: document.body.style.overflowY,
|
||||
overflow: document.body.style.overflow,
|
||||
};
|
||||
switchScrollingEffect();
|
||||
// Must be set after switchScrollingEffect
|
||||
document.body.style.overflow = 'hidden';
|
||||
} else if (!openCount) {
|
||||
// IE browser doesn't merge overflow style, need to set it separately
|
||||
// https://github.com/ant-design/ant-design/issues/19393
|
||||
if (cacheOverflow.overflow !== undefined) {
|
||||
document.body.style.overflow = cacheOverflow.overflow;
|
||||
}
|
||||
if (cacheOverflow.overflowX !== undefined) {
|
||||
document.body.style.overflowX = cacheOverflow.overflowX;
|
||||
}
|
||||
if (cacheOverflow.overflowY !== undefined) {
|
||||
document.body.style.overflowY = cacheOverflow.overflowY;
|
||||
}
|
||||
cacheOverflow = {};
|
||||
switchScrollingEffect(true);
|
||||
}
|
||||
switchScrollingEffect();
|
||||
document.body.style.overflow = 'hidden';
|
||||
},
|
||||
removeScrollingEffect() {
|
||||
const { getOpenCount } = this;
|
||||
const openCount = getOpenCount();
|
||||
if (openCount !== 0) {
|
||||
return;
|
||||
}
|
||||
document.body.style.overflow = '';
|
||||
switchScrollingEffect(true);
|
||||
// this.resetAdjustments();
|
||||
},
|
||||
// removeScrollingEffect() {
|
||||
// const { getOpenCount } = this;
|
||||
// const openCount = getOpenCount();
|
||||
// if (openCount !== 0) {
|
||||
// return;
|
||||
// }
|
||||
// document.body.style.overflow = '';
|
||||
// switchScrollingEffect(true);
|
||||
// // this.resetAdjustments();
|
||||
// },
|
||||
close(e) {
|
||||
this.__emit('close', e);
|
||||
},
|
||||
// checkScrollbar() {
|
||||
// let fullWindowWidth = window.innerWidth;
|
||||
// if (!fullWindowWidth) {
|
||||
// // workaround for missing window.innerWidth in IE8
|
||||
// const documentElementRect = document.documentElement.getBoundingClientRect();
|
||||
// fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
|
||||
// }
|
||||
// this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth;
|
||||
// if (this.bodyIsOverflowing) {
|
||||
// this.scrollbarWidth = getScrollBarSize();
|
||||
// }
|
||||
// },
|
||||
// resetScrollbar() {
|
||||
// document.body.style.paddingRight = '';
|
||||
// },
|
||||
// adjustDialog() {
|
||||
// if (this.$refs.wrap && this.scrollbarWidth !== undefined) {
|
||||
// const modalIsOverflowing =
|
||||
// this.$refs.wrap.scrollHeight > document.documentElement.clientHeight;
|
||||
// this.$refs.wrap.style.paddingLeft = `${
|
||||
// !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : ''
|
||||
// }px`;
|
||||
// this.$refs.wrap.style.paddingRight = `${
|
||||
// this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
|
||||
// }px`;
|
||||
// }
|
||||
// },
|
||||
// resetAdjustments() {
|
||||
// if (this.$refs.wrap) {
|
||||
// this.$refs.wrap.style.paddingLeft = this.$refs.wrap.style.paddingLeft = '';
|
||||
// }
|
||||
// },
|
||||
},
|
||||
render() {
|
||||
const { prefixCls, maskClosable, visible, wrapClassName, title, wrapProps } = this;
|
||||
|
@ -433,7 +419,7 @@ export default {
|
|||
style.display = null;
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<div class={`${prefixCls}-root`}>
|
||||
{this.getMaskElement()}
|
||||
<div
|
||||
tabIndex={-1}
|
||||
|
|
|
@ -37,6 +37,9 @@ function IDialogPropTypes() {
|
|||
closeIcon: PropTypes.any,
|
||||
forceRender: PropTypes.bool,
|
||||
getOpenCount: PropTypes.func,
|
||||
// https://github.com/ant-design/ant-design/issues/19771
|
||||
// https://github.com/react-component/dialog/issues/95
|
||||
focusTriggerAfterClose: PropTypes.bool,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import PropTypes from '../_util/vue-types';
|
|||
const ILazyRenderBoxPropTypes = {
|
||||
visible: PropTypes.bool,
|
||||
hiddenClassName: PropTypes.string,
|
||||
forceRender: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// based on vc-dialog 7.5.5
|
||||
// based on vc-dialog 7.5.14
|
||||
import DialogWrap from './DialogWrap';
|
||||
export default DialogWrap;
|
||||
|
|
Loading…
Reference in New Issue