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();
|
this.onClose && this.onClose();
|
||||||
messageBox.closeDialog(); // 解绑
|
messageBox.closeDialog(); // 解绑
|
||||||
if (this.lockScroll) {
|
if (this.lockScroll) {
|
||||||
setTimeout(() => {
|
setTimeout(this.restoreBodyStyle, 200);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
this.opened = false;
|
this.opened = false;
|
||||||
|
this.doAfterClose();
|
||||||
if (!this.transition) {
|
|
||||||
this.doAfterClose();
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.action) this.callback(this.action, this);
|
if (this.action) this.callback(this.action, this);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import "../mixins/mixins";
|
||||||
|
|
||||||
.v-modal-enter {
|
.v-modal-enter {
|
||||||
animation: v-modal-in .2s ease;
|
animation: v-modal-in .2s ease;
|
||||||
}
|
}
|
||||||
|
@ -31,3 +33,9 @@
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
background: #000;
|
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 merge from 'element-ui/src/utils/merge';
|
||||||
import PopupManager from 'element-ui/src/utils/popup/popup-manager';
|
import PopupManager from 'element-ui/src/utils/popup/popup-manager';
|
||||||
import getScrollBarWidth from '../scrollbar-width';
|
import getScrollBarWidth from '../scrollbar-width';
|
||||||
import { getStyle } from '../dom';
|
import { getStyle, addClass, removeClass, hasClass } from '../dom';
|
||||||
|
|
||||||
let idSeed = 1;
|
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;
|
let scrollBarWidth;
|
||||||
|
|
||||||
|
@ -55,10 +22,6 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
transition: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
openDelay: {},
|
openDelay: {},
|
||||||
closeDelay: {},
|
closeDelay: {},
|
||||||
zIndex: {},
|
zIndex: {},
|
||||||
|
@ -89,12 +52,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
|
||||||
if (this.transition) {
|
|
||||||
hookTransition(this.transition);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
this._popupId = 'popup-' + idSeed++;
|
this._popupId = 'popup-' + idSeed++;
|
||||||
PopupManager.register(this._popupId, this);
|
PopupManager.register(this._popupId, this);
|
||||||
|
@ -103,19 +60,16 @@ export default {
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
PopupManager.deregister(this._popupId);
|
PopupManager.deregister(this._popupId);
|
||||||
PopupManager.closeModal(this._popupId);
|
PopupManager.closeModal(this._popupId);
|
||||||
if (this.modal && this.bodyOverflow !== null && this.bodyOverflow !== 'hidden') {
|
|
||||||
document.body.style.overflow = this.bodyOverflow;
|
this.restoreBodyStyle();
|
||||||
document.body.style.paddingRight = this.bodyPaddingRight;
|
|
||||||
}
|
|
||||||
this.bodyOverflow = null;
|
|
||||||
this.bodyPaddingRight = null;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
opened: false,
|
opened: false,
|
||||||
bodyOverflow: null,
|
|
||||||
bodyPaddingRight: null,
|
bodyPaddingRight: null,
|
||||||
|
computedBodyPaddingRight: 0,
|
||||||
|
withoutHiddenClass: false,
|
||||||
rendered: false
|
rendered: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -186,17 +140,18 @@ export default {
|
||||||
}
|
}
|
||||||
PopupManager.openModal(this._popupId, PopupManager.nextZIndex(), this.modalAppendToBody ? undefined : dom, props.modalClass, props.modalFade);
|
PopupManager.openModal(this._popupId, PopupManager.nextZIndex(), this.modalAppendToBody ? undefined : dom, props.modalClass, props.modalFade);
|
||||||
if (props.lockScroll) {
|
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.bodyPaddingRight = document.body.style.paddingRight;
|
||||||
this.bodyOverflow = document.body.style.overflow;
|
this.computedBodyPaddingRight = parseInt(getStyle(document.body, 'paddingRight'), 10);
|
||||||
}
|
}
|
||||||
scrollBarWidth = getScrollBarWidth();
|
scrollBarWidth = getScrollBarWidth();
|
||||||
let bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight;
|
let bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight;
|
||||||
let bodyOverflowY = getStyle(document.body, 'overflowY');
|
let bodyOverflowY = getStyle(document.body, 'overflowY');
|
||||||
if (scrollBarWidth > 0 && (bodyHasOverflow || bodyOverflowY === 'scroll')) {
|
if (scrollBarWidth > 0 && (bodyHasOverflow || bodyOverflowY === 'scroll') && this.withoutHiddenClass) {
|
||||||
document.body.style.paddingRight = scrollBarWidth + 'px';
|
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();
|
this.onOpen && this.onOpen();
|
||||||
|
|
||||||
if (!this.transition) {
|
this.doAfterOpen();
|
||||||
this.doAfterOpen();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
doAfterOpen() {
|
doAfterOpen() {
|
||||||
|
@ -245,26 +198,24 @@ export default {
|
||||||
this.onClose && this.onClose();
|
this.onClose && this.onClose();
|
||||||
|
|
||||||
if (this.lockScroll) {
|
if (this.lockScroll) {
|
||||||
setTimeout(() => {
|
setTimeout(this.restoreBodyStyle, 200);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.opened = false;
|
this.opened = false;
|
||||||
|
|
||||||
if (!this.transition) {
|
this.doAfterClose();
|
||||||
this.doAfterClose();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
doAfterClose() {
|
doAfterClose() {
|
||||||
PopupManager.closeModal(this._popupId);
|
PopupManager.closeModal(this._popupId);
|
||||||
this._closing = false;
|
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,
|
type: Number,
|
||||||
default: 35
|
default: 35
|
||||||
},
|
},
|
||||||
transition: String,
|
|
||||||
appendToBody: {
|
appendToBody: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
|
|
@ -13,6 +13,7 @@ const Popup = Object.assign({}, VuePopup, {
|
||||||
describe('Mixin:vue-popup', () => {
|
describe('Mixin:vue-popup', () => {
|
||||||
let vm;
|
let vm;
|
||||||
before(() => {
|
before(() => {
|
||||||
|
document.body.className = '';
|
||||||
const modals = document.querySelectorAll('.v-modal');
|
const modals = document.querySelectorAll('.v-modal');
|
||||||
[].forEach.call(modals, modal => {
|
[].forEach.call(modals, modal => {
|
||||||
modal &&
|
modal &&
|
||||||
|
@ -49,13 +50,13 @@ describe('Mixin:vue-popup', () => {
|
||||||
it('lock scroll', done => {
|
it('lock scroll', done => {
|
||||||
vm = createTest(Popup, { modal: true });
|
vm = createTest(Popup, { modal: true });
|
||||||
vm.open();
|
vm.open();
|
||||||
expect(document.body.style.overflow).to.equal('hidden');
|
expect(document.body.classList.contains('el-popup-parent--hidden')).to.be.true;
|
||||||
vm.close();
|
vm.close();
|
||||||
destroyVM(vm);
|
destroyVM(vm);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
vm = createTest(Popup, { modal: true, lockScroll: false });
|
vm = createTest(Popup, { modal: true, lockScroll: false });
|
||||||
vm.open();
|
vm.open();
|
||||||
expect(document.body.style.overflow).to.not.equal('hidden');
|
expect(document.body.classList.contains('el-popup-parent--hidden')).to.be.false;
|
||||||
done();
|
done();
|
||||||
}, 200);
|
}, 200);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue