mirror of https://github.com/ElemeFE/element
Popup: lockScroll uses class instead of inline style, remove redundant code (#11114)
* Popup: when popup open, use a class to prevent body scroll * popup,MessageBox,vue-popper: remove redundant code * popup: use getStyle to get document body's paddingRight * Update mixin.vue-popup.spec.js * Update mixin.vue-popup.spec.jspull/11144/head
parent
6289144d84
commit
63844fd845
|
@ -161,20 +161,10 @@
|
|||
this.onClose && this.onClose();
|
||||
messageBox.closeDialog(); // 解绑
|
||||
if (this.lockScroll) {
|
||||
setTimeout(() => {
|
||||
if (this.modal && this.bodyOverflow !== 'hidden') {
|
||||
document.body.style.overflow = this.bodyOverflow;
|
||||
document.body.style.paddingRight = this.bodyPaddingRight;
|
||||
}
|
||||
this.bodyOverflow = null;
|
||||
this.bodyPaddingRight = null;
|
||||
}, 200);
|
||||
setTimeout(this.restoreBodyStyle, 200);
|
||||
}
|
||||
this.opened = false;
|
||||
|
||||
if (!this.transition) {
|
||||
this.doAfterClose();
|
||||
}
|
||||
this.doAfterClose();
|
||||
setTimeout(() => {
|
||||
if (this.action) this.callback(this.action, this);
|
||||
});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
@import "../mixins/mixins";
|
||||
|
||||
.v-modal-enter {
|
||||
animation: v-modal-in .2s ease;
|
||||
}
|
||||
|
@ -31,3 +33,9 @@
|
|||
opacity: 0.5;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
@include b(popup-parent) {
|
||||
@include m(hidden) {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,42 +2,9 @@ import Vue from 'vue';
|
|||
import merge from 'element-ui/src/utils/merge';
|
||||
import PopupManager from 'element-ui/src/utils/popup/popup-manager';
|
||||
import getScrollBarWidth from '../scrollbar-width';
|
||||
import { getStyle } from '../dom';
|
||||
import { getStyle, addClass, removeClass, hasClass } from '../dom';
|
||||
|
||||
let idSeed = 1;
|
||||
const transitions = [];
|
||||
|
||||
const hookTransition = (transition) => {
|
||||
if (transitions.indexOf(transition) !== -1) return;
|
||||
|
||||
const getVueInstance = (element) => {
|
||||
let instance = element.__vue__;
|
||||
if (!instance) {
|
||||
const textNode = element.previousSibling;
|
||||
if (textNode.__vue__) {
|
||||
instance = textNode.__vue__;
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
};
|
||||
|
||||
Vue.transition(transition, {
|
||||
afterEnter(el) {
|
||||
const instance = getVueInstance(el);
|
||||
|
||||
if (instance) {
|
||||
instance.doAfterOpen && instance.doAfterOpen();
|
||||
}
|
||||
},
|
||||
afterLeave(el) {
|
||||
const instance = getVueInstance(el);
|
||||
|
||||
if (instance) {
|
||||
instance.doAfterClose && instance.doAfterClose();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let scrollBarWidth;
|
||||
|
||||
|
@ -55,10 +22,6 @@ export default {
|
|||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
transition: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
openDelay: {},
|
||||
closeDelay: {},
|
||||
zIndex: {},
|
||||
|
@ -89,12 +52,6 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.transition) {
|
||||
hookTransition(this.transition);
|
||||
}
|
||||
},
|
||||
|
||||
beforeMount() {
|
||||
this._popupId = 'popup-' + idSeed++;
|
||||
PopupManager.register(this._popupId, this);
|
||||
|
@ -103,19 +60,16 @@ export default {
|
|||
beforeDestroy() {
|
||||
PopupManager.deregister(this._popupId);
|
||||
PopupManager.closeModal(this._popupId);
|
||||
if (this.modal && this.bodyOverflow !== null && this.bodyOverflow !== 'hidden') {
|
||||
document.body.style.overflow = this.bodyOverflow;
|
||||
document.body.style.paddingRight = this.bodyPaddingRight;
|
||||
}
|
||||
this.bodyOverflow = null;
|
||||
this.bodyPaddingRight = null;
|
||||
|
||||
this.restoreBodyStyle();
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
opened: false,
|
||||
bodyOverflow: null,
|
||||
bodyPaddingRight: null,
|
||||
computedBodyPaddingRight: 0,
|
||||
withoutHiddenClass: false,
|
||||
rendered: false
|
||||
};
|
||||
},
|
||||
|
@ -186,17 +140,18 @@ export default {
|
|||
}
|
||||
PopupManager.openModal(this._popupId, PopupManager.nextZIndex(), this.modalAppendToBody ? undefined : dom, props.modalClass, props.modalFade);
|
||||
if (props.lockScroll) {
|
||||
if (!this.bodyOverflow) {
|
||||
this.withoutHiddenClass = !hasClass(document.body, 'el-popup-parent--hidden');
|
||||
if (this.withoutHiddenClass) {
|
||||
this.bodyPaddingRight = document.body.style.paddingRight;
|
||||
this.bodyOverflow = document.body.style.overflow;
|
||||
this.computedBodyPaddingRight = parseInt(getStyle(document.body, 'paddingRight'), 10);
|
||||
}
|
||||
scrollBarWidth = getScrollBarWidth();
|
||||
let bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight;
|
||||
let bodyOverflowY = getStyle(document.body, 'overflowY');
|
||||
if (scrollBarWidth > 0 && (bodyHasOverflow || bodyOverflowY === 'scroll')) {
|
||||
document.body.style.paddingRight = scrollBarWidth + 'px';
|
||||
if (scrollBarWidth > 0 && (bodyHasOverflow || bodyOverflowY === 'scroll') && this.withoutHiddenClass) {
|
||||
document.body.style.paddingRight = this.computedBodyPaddingRight + scrollBarWidth + 'px';
|
||||
}
|
||||
document.body.style.overflow = 'hidden';
|
||||
addClass(document.body, 'el-popup-parent--hidden');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,9 +164,7 @@ export default {
|
|||
|
||||
this.onOpen && this.onOpen();
|
||||
|
||||
if (!this.transition) {
|
||||
this.doAfterOpen();
|
||||
}
|
||||
this.doAfterOpen();
|
||||
},
|
||||
|
||||
doAfterOpen() {
|
||||
|
@ -245,26 +198,24 @@ export default {
|
|||
this.onClose && this.onClose();
|
||||
|
||||
if (this.lockScroll) {
|
||||
setTimeout(() => {
|
||||
if (this.modal && this.bodyOverflow !== 'hidden') {
|
||||
document.body.style.overflow = this.bodyOverflow;
|
||||
document.body.style.paddingRight = this.bodyPaddingRight;
|
||||
}
|
||||
this.bodyOverflow = null;
|
||||
this.bodyPaddingRight = null;
|
||||
}, 200);
|
||||
setTimeout(this.restoreBodyStyle, 200);
|
||||
}
|
||||
|
||||
this.opened = false;
|
||||
|
||||
if (!this.transition) {
|
||||
this.doAfterClose();
|
||||
}
|
||||
this.doAfterClose();
|
||||
},
|
||||
|
||||
doAfterClose() {
|
||||
PopupManager.closeModal(this._popupId);
|
||||
this._closing = false;
|
||||
},
|
||||
|
||||
restoreBodyStyle() {
|
||||
if (this.modal && this.withoutHiddenClass) {
|
||||
document.body.style.paddingRight = this.bodyPaddingRight;
|
||||
removeClass(document.body, 'el-popup-parent--hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -39,7 +39,6 @@ export default {
|
|||
type: Number,
|
||||
default: 35
|
||||
},
|
||||
transition: String,
|
||||
appendToBody: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
|
|
|
@ -13,6 +13,7 @@ const Popup = Object.assign({}, VuePopup, {
|
|||
describe('Mixin:vue-popup', () => {
|
||||
let vm;
|
||||
before(() => {
|
||||
document.body.className = '';
|
||||
const modals = document.querySelectorAll('.v-modal');
|
||||
[].forEach.call(modals, modal => {
|
||||
modal &&
|
||||
|
@ -49,13 +50,13 @@ describe('Mixin:vue-popup', () => {
|
|||
it('lock scroll', done => {
|
||||
vm = createTest(Popup, { modal: true });
|
||||
vm.open();
|
||||
expect(document.body.style.overflow).to.equal('hidden');
|
||||
expect(document.body.classList.contains('el-popup-parent--hidden')).to.be.true;
|
||||
vm.close();
|
||||
destroyVM(vm);
|
||||
setTimeout(() => {
|
||||
vm = createTest(Popup, { modal: true, lockScroll: false });
|
||||
vm.open();
|
||||
expect(document.body.style.overflow).to.not.equal('hidden');
|
||||
expect(document.body.classList.contains('el-popup-parent--hidden')).to.be.false;
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue