[Improvement] Popup: add click-overlay event (#647)

This commit is contained in:
neverland 2018-02-24 15:22:41 +08:00 committed by GitHub
parent c0f870ceb9
commit 5d25d7aff9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 45 deletions

View File

@ -49,3 +49,9 @@ Use `position` prop to set popup display position
| transition | Transition | `String` | `popup-slide` | - | | transition | Transition | `String` | `popup-slide` | - |
| prevent-scroll | Prevent background scroll | `Boolean` | `false` | - | | prevent-scroll | Prevent background scroll | `Boolean` | `false` | - |
| get-container | Return the mount node for Popup | `Function` | - | `() => HTMLElement` | | get-container | Return the mount node for Popup | `Function` | - | `() => HTMLElement` |
### Event
| Event | Description | Arguments |
|-----------|-----------|-----------|
| click-overlay | Triggered when click overlay | - |

View File

@ -49,3 +49,9 @@ export default {
| transition | transition 名称 | `String` | `popup-slide` | - | | transition | transition 名称 | `String` | `popup-slide` | - |
| prevent-scroll | 是否防止滚动穿透 | `Boolean` | `false` | - | | prevent-scroll | 是否防止滚动穿透 | `Boolean` | `false` | - |
| get-container | 指定弹出层挂载的 HTML 节点 | `Function` | - | `() => HTMLElement` | | get-container | 指定弹出层挂载的 HTML 节点 | `Function` | - | `() => HTMLElement` |
### Event
| 事件名 | 说明 | 参数 |
|-----------|-----------|-----------|
| click-overlay | 点击蒙层时触发 | - |

View File

@ -113,7 +113,7 @@ export default {
} }
if (this.overlay) { if (this.overlay) {
manager.openModal(this, { manager.open(this, {
id: this._popupId, id: this._popupId,
dom: this.$el, dom: this.$el,
zIndex: context.plusKey('zIndex'), zIndex: context.plusKey('zIndex'),
@ -146,7 +146,7 @@ export default {
}, },
doAfterClose() { doAfterClose() {
manager.closeModal(this._popupId); manager.close(this._popupId);
if (this.lockOnScroll) { if (this.lockOnScroll) {
document.body.classList.remove('van-overflow-hidden'); document.body.classList.remove('van-overflow-hidden');

View File

@ -2,68 +2,48 @@ import Vue from 'vue';
import Modal from './Modal'; import Modal from './Modal';
import context from './context'; import context from './context';
const modalDefaultConfig = { const defaultConfig = {
className: '', className: '',
customStyle: {} customStyle: {}
}; };
const manager = { export default {
getModal() { open(vm, config) {
let { modal } = context;
if (!modal) {
const ModalConstructor = Vue.extend(Modal);
modal = new ModalConstructor({
el: document.createElement('div')
});
modal.$on('click', () => {
manager.onClickOverlay();
});
context.modal = modal;
}
return modal;
},
// close popup when click modal && closeOnClickOverlay is true
onClickOverlay() {
const { top } = context;
if (top) {
const { instance } = top;
if (instance && instance.closeOnClickOverlay) {
instance.close();
}
}
},
openModal(instance, config) {
const { id, dom } = config; const { id, dom } = config;
const exist = context.stack.some(item => item.id === id); const exist = context.stack.some(item => item.id === id);
/* istanbul ignore next */ /* istanbul ignore next */
if (!exist) { if (!exist) {
const targetNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body; const targetNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body;
context.stack.push({ instance, id, config, targetNode }); context.stack.push({ vm, id, config, targetNode });
this.updateModal(); this.update();
}; };
}, },
closeModal(id) { close(id) {
const { stack } = context; const { stack } = context;
if (stack.length) { if (stack.length) {
if (context.top.id === id) { if (context.top.id === id) {
stack.pop(); stack.pop();
this.updateModal(); this.update();
} else { } else {
context.stack = stack.filter(item => item.id !== id); context.stack = stack.filter(item => item.id !== id);
} }
} }
}, },
updateModal() { update() {
const modal = this.getModal(); let { modal } = context;
if (!modal) {
modal = new (Vue.extend(Modal))({
el: document.createElement('div')
});
modal.$on('click', this.onClick);
context.modal = modal;
}
if (modal.$el.parentNode) { if (modal.$el.parentNode) {
modal.visible = false; modal.visible = false;
@ -74,12 +54,21 @@ const manager = {
targetNode.appendChild(modal.$el); targetNode.appendChild(modal.$el);
Object.assign(modal, { Object.assign(modal, {
...modalDefaultConfig, ...defaultConfig,
...config, ...config,
visible: true visible: true
}); });
} }
},
// close popup when click modal && closeOnClickOverlay is true
onClick() {
if (context.top) {
const { vm } = context.top;
if (vm) {
vm.$emit('click-overlay');
vm.closeOnClickOverlay && vm.close();
}
}
} }
}; };
export default manager;

View File

@ -100,9 +100,8 @@ describe('Popup', () => {
expect(wrapper.hasClass('van-popup')).to.be.true; expect(wrapper.hasClass('van-popup')).to.be.true;
const modal = document.querySelector('.van-modal');
setTimeout(() => { setTimeout(() => {
const modal = document.querySelector('.van-modal');
triggerTouch(modal, 'touchstart', 0, 0); triggerTouch(modal, 'touchstart', 0, 0);
triggerTouch(modal, 'touchmove', 0, 10); triggerTouch(modal, 'touchmove', 0, 10);
triggerTouch(modal, 'touchmove', 0, 30); triggerTouch(modal, 'touchmove', 0, 30);