From ccf868c239de511d86ae7368e080d9137523c67d Mon Sep 17 00:00:00 2001 From: neverland Date: Fri, 24 Nov 2017 14:18:14 +0800 Subject: [PATCH] [bugfix] Popup: update overlay style & class (#349) * fix: Tabbar icon line-height * [new feature] progress add showPivot prop * [new feature] TabItem support vue-router * [new feature] update document header style * [Doc] add toast english ducoment * [bugfix] Search box-sizing wrong * [Doc] update vant-demo respo * [Doc] translate theme & demo pages * [Doc] add Internationalization document * [bugfix] remove unnecessary props * [fix] optimize clickoutside * [new feature] optimize find-parent * [new feature]: change document title accordinng to language * [new feature] Pagination code review * [improvement] adjust icon-font unicode * [improvement] Icon spinner color inherit * [improvement] icon default width * [bugfix] DateTimePicker validate date props * [bugfix] Tab item text ellipsis * [improvement] optimize single line ellipsis * [Improvement] optimzie staticClass * [Improvement] Button: use sfc instread of jsx * [Improvement] update actionsheet close icon style * fix: yarn.lock * fix: icon test cases * [bugfix] errors during ssr * [Improvement] SubmitBar add left slot * [new feature] ImagePreview support manually close * fix: ImagePreview test case * [Doc] add switch lang button in mobile * [bugfix] Popup overlay style update --- docs/markdown/en-US/popup.md | 2 + docs/markdown/zh-CN/popup.md | 10 ++-- docs/src/components/DemoList.vue | 2 + packages/mixins/popup/Modal.vue | 30 ++++++++++ packages/mixins/popup/index.js | 5 +- packages/mixins/popup/popup-context.js | 6 +- packages/mixins/popup/popup-manager.js | 81 ++++++++++++++------------ 7 files changed, 91 insertions(+), 45 deletions(-) create mode 100644 packages/mixins/popup/Modal.vue diff --git a/docs/markdown/en-US/popup.md b/docs/markdown/en-US/popup.md index 5e14339c6..598bf31a5 100644 --- a/docs/markdown/en-US/popup.md +++ b/docs/markdown/en-US/popup.md @@ -43,6 +43,8 @@ Use `position` prop to set popup display position | overlay | Whether to show overlay | `Boolean` | `true` | - | | lockOnScroll | Lock body scroll | `Boolean` | `false` | - | | position | Position | `String` | - | `top` `bottom` `right` `left` | +| overlayClass | Custom overlay class | `String` | `` | - | +| overlayStyle | Custom overlay style | `Object` | `` | - | | closeOnClickOverlay | Close popup when click overlay | `Boolean` | `true` | - | | transition | Transition | `String` | `popup-slide` | - | | preventScroll | Prevent background scroll | `Boolean` | `false` | - | diff --git a/docs/markdown/zh-CN/popup.md b/docs/markdown/zh-CN/popup.md index 7492131b1..905082121 100644 --- a/docs/markdown/zh-CN/popup.md +++ b/docs/markdown/zh-CN/popup.md @@ -40,9 +40,11 @@ export default { | 参数 | 说明 | 类型 | 默认值 | 可选值 | |-----------|-----------|-----------|-------------|-------------| | v-model | 当前组件是否显示 | `Boolean` | `false` | - | -| overlay | 是否显示背景遮罩层 | `Boolean` | `true` | - | +| overlay | 是否显示背景蒙层 | `Boolean` | `true` | - | | lockOnScroll | 背景是否跟随滚动 | `Boolean` | `false` | - | -| position | 弹出层位置 | `String` | - | `top` `bottom` `right` `left` | -| closeOnClickOverlay | 点击遮罩层是否关闭弹出层 | `Boolean` | `true` | - | -| transition | 弹出层的`transition` | `String` | `popup-slide` | - | +| position | Popup 位置 | `String` | - | `top` `bottom` `right` `left` | +| overlayClass | 自定义蒙层 class | `String` | `` | - | +| overlayStyle | 自定义蒙层样式 | `Object` | `` | - | +| closeOnClickOverlay | 点击蒙层是否关闭 Popup | `Boolean` | `true` | - | +| transition | transition 名称 | `String` | `popup-slide` | - | | preventScroll | 是否防止滚动穿透 | `Boolean` | `false` | - | diff --git a/docs/src/components/DemoList.vue b/docs/src/components/DemoList.vue index 6ff02a794..153bd0a69 100644 --- a/docs/src/components/DemoList.vue +++ b/docs/src/components/DemoList.vue @@ -49,6 +49,8 @@ export default { methods: { switchLang(lang) { + const from = lang === 'zh-CN' ? 'en-US' : 'zh-CN'; + this.$router.push(this.$route.path.replace(from, lang)); setLang(lang); } } diff --git a/packages/mixins/popup/Modal.vue b/packages/mixins/popup/Modal.vue new file mode 100644 index 000000000..a9c663a73 --- /dev/null +++ b/packages/mixins/popup/Modal.vue @@ -0,0 +1,30 @@ + + + diff --git a/packages/mixins/popup/index.js b/packages/mixins/popup/index.js index 38c69e677..522a93e86 100644 --- a/packages/mixins/popup/index.js +++ b/packages/mixins/popup/index.js @@ -112,9 +112,10 @@ export default { id: this._popupId, zIndex: context.plusKeyByOne('zIndex'), dom: this.$el, - extraClass: this.overlayClass, - extraStyle: this.overlayStyle + className: this.overlayClass, + customStyle: this.overlayStyle }); + if (this.lockOnScroll) { document.body.classList.add('van-overflow-hidden'); } diff --git a/packages/mixins/popup/popup-context.js b/packages/mixins/popup/popup-context.js index 81035f451..14039e53c 100644 --- a/packages/mixins/popup/popup-context.js +++ b/packages/mixins/popup/popup-context.js @@ -2,14 +2,14 @@ const PopupContext = { idSeed: 1, zIndex: 2000, instances: {}, - modalStack: [], + stack: [], plusKeyByOne(key) { return this[key]++; }, - get topModal() { - return this.modalStack[this.modalStack.length - 1]; + get top() { + return this.stack[this.stack.length - 1]; } }; diff --git a/packages/mixins/popup/popup-manager.js b/packages/mixins/popup/popup-manager.js index 4da186d7f..fc632526e 100644 --- a/packages/mixins/popup/popup-manager.js +++ b/packages/mixins/popup/popup-manager.js @@ -1,17 +1,22 @@ +import Vue from 'vue'; +import Modal from './Modal'; import context from './popup-context'; +const modalDefaultConfig = { + className: '', + customStyle: {} +}; + const PopupManager = { getModal() { let { modal } = context; if (!modal) { - modal = document.createElement('div'); - modal.classList.add('van-modal'); - modal.addEventListener('touchmove', event => { - event.preventDefault(); - event.stopPropagation(); + const ModalConstructor = Vue.extend(Modal); + modal = new ModalConstructor({ + el: document.createElement('div') }); - modal.addEventListener('click', () => { + modal.$on('click', () => { PopupManager.handleOverlayClick(); }); @@ -23,52 +28,56 @@ const PopupManager = { // close popup when click modal && closeOnClickOverlay is true handleOverlayClick() { - const { topModal } = context; - if (topModal) { - const instance = context.instances[topModal.id]; + const { top } = context; + if (top) { + const instance = context.instances[top.id]; if (instance && instance.closeOnClickOverlay) { instance.close(); } } }, - openModal({ id, zIndex, dom, extraClass, extraStyle }) { - const { modalStack } = context; - const exist = modalStack.some(item => item.id === id); + openModal(config) { + const { id, dom } = config; + const exist = context.stack.some(item => item.id === id); if (!exist) { - const modal = this.getModal(); - if (extraClass) { - modal.classList.add(extraClass); - } - if (extraStyle) { - modal.style.cssText = `${modal.style.cssText} ${extraStyle}`; - } - modal.style.zIndex = zIndex; - - const parentNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body; - parentNode.appendChild(modal); - modalStack.push({ id, zIndex, parentNode }); + const targetNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body; + context.stack.push({ id, config, targetNode }); + this.updateModal(); }; }, closeModal(id) { - const { modalStack } = context; + const { stack } = context; - if (modalStack.length) { - if (context.topModal.id === id) { - const modal = this.getModal(); - modalStack.pop(); - modal.parentNode.removeChild(modal); - if (modalStack.length) { - const { topModal } = context; - modal.style.zIndex = topModal.zIndex; - topModal.parentNode.appendChild(modal); - } + if (stack.length) { + if (context.top.id === id) { + stack.pop(); + this.updateModal(); } else { - context.modalStack = modalStack.filter(item => item.id !== id); + context.stack = stack.filter(item => item.id !== id); } } + }, + + updateModal() { + const modal = this.getModal(); + const el = modal.$el; + + if (el.parentNode) { + el.parentNode.removeChild(el); + } + + if (context.top) { + const { targetNode, config } = context.top; + + targetNode.appendChild(el); + Object.assign(modal, { + ...modalDefaultConfig, + ...config + }); + } } };