Files
vant/src/mixins/popup/popup-manager.js
T
2017-03-10 17:16:22 +08:00

138 lines
3.1 KiB
JavaScript

import Vue from 'vue';
import merge from 'src/utils/merge';
import { addClass } from 'src/utils/dom';
let popupContext;
if (Vue.prototype.$isServer) {
popupContext = global.popupContext || {};
global.popupContext = popupContext;
} else {
popupContext = window.popupContext || {};
window.popupContext = popupContext;
}
popupContext = merge(popupContext, {
hasModal: false,
instances: {},
modalStack: []
});
const getModal = function() {
let modalDom = PopupManager.modalDom;
if (modalDom) {
popupContext.hasModal = true;
} else {
popupContext.hasModal = false;
modalDom = document.createElement('div');
PopupManager.modalDom = modalDom;
modalDom.addEventListener('touchmove', function(event) {
event.preventDefault();
event.stopPropagation();
});
modalDom.addEventListener('click', function() {
PopupManager.handleOverlayClick && PopupManager.handleOverlayClick();
});
}
return modalDom;
};
const PopupManager = {
zIndex: 2000,
nextZIndex() {
return this.zIndex++;
},
getInstance(id) {
return popupContext.instances[id];
},
register(id, instance) {
if (id && instance) {
popupContext.instances[id] = instance;
}
},
deregister(id) {
if (id) {
popupContext.instances[id] = null;
delete popupContext.instances[id];
}
},
/**
* 遮罩层点击回调,`closeOnClickOverlay`为`true`时会关闭当前`popup`
*/
handleOverlayClick() {
const topModal = popupContext.modalStack[popupContext.modalStack.length - 1];
if (!topModal) return;
const instance = PopupManager.getInstance(topModal.id);
if (instance && instance.closeOnClickOverlay) {
instance.close();
}
},
openModal(id, zIndex, dom) {
if (!id || zIndex === undefined) return;
const modalStack = popupContext.modalStack;
for (let i = 0, len = modalStack.length; i < len; i++) {
const item = modalStack[i];
if (item.id === id) {
return;
}
}
const modalDom = getModal();
addClass(modalDom, 'zan-modal');
document.body.appendChild(modalDom);
if (zIndex) {
modalDom.style.zIndex = zIndex;
}
modalDom.style.display = '';
popupContext.modalStack.push({ id: id, zIndex: zIndex });
},
closeModal(id) {
const modalStack = popupContext.modalStack;
const modalDom = getModal();
if (modalStack.length > 0) {
const topItem = modalStack[modalStack.length - 1];
if (topItem.id === id) {
modalStack.pop();
if (modalStack.length > 0) {
modalDom.style.zIndex = modalStack[modalStack.length - 1].zIndex;
}
} else {
for (let i = modalStack.length - 1; i >= 0; i--) {
if (modalStack[i].id === id) {
modalStack.splice(i, 1);
break;
}
}
}
}
if (modalStack.length === 0) {
setTimeout(() => {
if (modalDom.parentNode) modalDom.parentNode.removeChild(modalDom);
modalDom.style.display = 'none';
this.modalDom = null;
}, 200);
}
}
};
export default PopupManager;