diff --git a/docs/demos/views/popup.vue b/docs/demos/views/popup.vue
index b73aba431..85741ce59 100644
--- a/docs/demos/views/popup.vue
+++ b/docs/demos/views/popup.vue
@@ -25,8 +25,12 @@
{{ $t('button5') }}
-
+
{{ $t('button6') }}
+ {{ $t('button5') }}
+
+ {{ $t('button6') }}
+
@@ -60,7 +64,8 @@ export default {
show1: false,
show2: false,
show3: false,
- show4: false
+ show4: false,
+ show5: false
};
},
@@ -94,7 +99,6 @@ export default {
.van-popup {
width: 60%;
padding: 20px;
- border-radius: 5px;
box-sizing: border-box;
&--bottom {
@@ -109,7 +113,7 @@ export default {
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
-
+
.van-tab__pane:not(:first-child) {
padding: 10px;
line-height: 1.4;
diff --git a/packages/image-preview/image-preview.vue b/packages/image-preview/image-preview.vue
index 49feed3d7..5a19270a1 100644
--- a/packages/image-preview/image-preview.vue
+++ b/packages/image-preview/image-preview.vue
@@ -69,7 +69,7 @@ export default create({
// prevent long tap to close component
const deltaTime = new Date() - this.touchStartTime;
if (deltaTime < 100 && Math.abs(this.deltaX) < 20 && Math.abs(this.deltaY) < 20) {
- this.close();
+ this.$emit('input', false);
}
}
}
diff --git a/packages/mixins/popup/context.js b/packages/mixins/popup/context.js
index 824941339..1d02bc857 100644
--- a/packages/mixins/popup/context.js
+++ b/packages/mixins/popup/context.js
@@ -2,6 +2,7 @@ export default {
id: 1,
zIndex: 2000,
stack: [],
+ lockCount: 0,
plusKey(key) {
return this[key]++;
diff --git a/packages/mixins/popup/index.js b/packages/mixins/popup/index.js
index bca493b4f..89176d3ec 100644
--- a/packages/mixins/popup/index.js
+++ b/packages/mixins/popup/index.js
@@ -57,14 +57,26 @@ export default {
}
},
+ activated() {
+ /* istanbul ignore next */
+ if (this.value) {
+ this.open();
+ }
+ },
+
beforeDestroy() {
this.close();
},
+ deactivated() {
+ /* istanbul ignore next */
+ this.close();
+ },
+
methods: {
open() {
/* istanbul ignore next */
- if (this.$isServer) {
+ if (this.$isServer || this.opened) {
return;
}
@@ -73,30 +85,41 @@ export default {
context.zIndex = this.zIndex;
}
- if (this.lockScroll) {
- document.body.classList.add('van-overflow-hidden');
- on(document, 'touchstart', this.onTouchStart);
- on(document, 'touchmove', this.onTouchMove);
- }
-
+ this.opened = true;
this.renderOverlay();
- this.$emit('input', true);
+
+ if (this.lockScroll) {
+ if (!context.lockCount) {
+ document.body.classList.add('van-overflow-hidden');
+ on(document, 'touchstart', this.onTouchStart);
+ on(document, 'touchmove', this.onTouchMove);
+ }
+ context.lockCount++;
+ }
},
close() {
- if (this.lockScroll) {
- document.body.classList.remove('van-overflow-hidden');
- off(document, 'touchstart', this.onTouchStart);
- off(document, 'touchmove', this.onTouchMove);
+ if (!this.opened) {
+ return;
}
+ if (this.lockScroll) {
+ context.lockCount--;
+ if (!context.lockCount) {
+ document.body.classList.remove('van-overflow-hidden');
+ off(document, 'touchstart', this.onTouchStart);
+ off(document, 'touchmove', this.onTouchMove);
+ }
+ }
+
+ this.opened = false;
manager.close(this._popupId);
- this.$emit('input', false);
},
move() {
if (this.getContainer) {
this.getContainer().appendChild(this.$el);
+ /* istanbul ignore if */
} else if (this.$parent) {
this.$parent.$el.appendChild(this.$el);
}
diff --git a/packages/mixins/popup/manager.js b/packages/mixins/popup/manager.js
index 73daf599c..68649bb8a 100644
--- a/packages/mixins/popup/manager.js
+++ b/packages/mixins/popup/manager.js
@@ -9,10 +9,8 @@ const defaultConfig = {
export default {
open(vm, config) {
- const exist = context.stack.some(item => item.vm._popupId === vm._popupId);
-
/* istanbul ignore next */
- if (!exist) {
+ if (!context.stack.some(item => item.vm._popupId === vm._popupId)) {
const el = vm.$el;
const targetNode = el && el.parentNode && el.parentNode.nodeType !== 11 ? el.parentNode : document.body;
context.stack.push({ vm, config, targetNode });
@@ -66,7 +64,7 @@ export default {
if (context.top) {
const { vm } = context.top;
vm.$emit('click-overlay');
- vm.closeOnClickOverlay && vm.close();
+ vm.closeOnClickOverlay && vm.$emit('input', false);
}
}
};
diff --git a/test/specs/popup.spec.js b/test/specs/popup.spec.js
index 6676c532e..e40bd51b5 100644
--- a/test/specs/popup.spec.js
+++ b/test/specs/popup.spec.js
@@ -24,7 +24,8 @@ describe('Popup', () => {
propsData: {
value: false,
zIndex: 100,
- overlay: false
+ overlay: false,
+ lockScroll: false
}
});
@@ -60,30 +61,6 @@ describe('Popup', () => {
expect(wrapper.instance().currentTransition).to.equal('popup-fade');
});
- it('popup prevent scroll', (done) => {
- wrapper = mount(Popup, {
- propsData: {
- value: true
- }
- });
-
- expect(wrapper.hasClass('van-popup')).to.be.true;
-
- setTimeout(() => {
- expect(wrapper.element.style.display).to.equal('');
- wrapper.vm.value = false;
- triggerTouch(document, 'touchstart', 0, 0);
- triggerTouch(document, 'touchmove', 0, 10);
- triggerTouch(document, 'touchmove', 0, 30);
- triggerTouch(document, 'touchmove', 0, -30);
-
- setTimeout(() => {
- expect(wrapper.element.style.display).to.equal('none');
- done();
- }, 500);
- }, 300);
- });
-
it('popup modal', (done) => {
wrapper = mount(Popup, {
propsData: {
@@ -113,6 +90,30 @@ describe('Popup', () => {
}, 300);
});
+ it('popup prevent scroll', (done) => {
+ wrapper = mount(Popup, {
+ propsData: {
+ value: true
+ }
+ });
+
+ expect(wrapper.hasClass('van-popup')).to.be.true;
+
+ setTimeout(() => {
+ expect(wrapper.element.style.display).to.equal('');
+ wrapper.vm.value = false;
+ triggerTouch(document, 'touchstart', 0, 0);
+ triggerTouch(document, 'touchmove', 0, 10);
+ triggerTouch(document, 'touchmove', 0, 30);
+ triggerTouch(document, 'touchmove', 0, -30);
+
+ setTimeout(() => {
+ expect(wrapper.element.style.display).to.equal('none');
+ done();
+ }, 500);
+ }, 300);
+ });
+
it('treat empty string as true for boolean props', () => {
wrapper = mount(Popup, {
propsData: {
@@ -127,7 +128,9 @@ describe('Popup', () => {
it('get container prop', done => {
const testNode = document.createElement('div');
+ const testNode2 = document.createElement('div');
document.body.appendChild(testNode);
+ document.body.appendChild(testNode2);
wrapper = mount(Popup, {
propsData: {
@@ -136,11 +139,44 @@ describe('Popup', () => {
});
expect(wrapper.vm.$el.parentNode === testNode).to.be.true;
- wrapper.vm.getContainer = () => document.body;
+ wrapper.vm.getContainer = () => testNode2;
setTimeout(() => {
- expect(wrapper.vm.$el.parentNode === document.body).to.be.true;
+ expect(wrapper.vm.$el.parentNode === testNode2).to.be.true;
+ wrapper.vm.getContainer = null;
done();
}, 100);
});
+
+ it('watch overlay change', done => {
+ const testNode = document.createElement('div');
+ document.body.appendChild(testNode);
+
+ wrapper = mount(Popup, {
+ propsData: {
+ overlay: false,
+ getContainer: () => testNode
+ }
+ });
+
+ expect(testNode.querySelectorAll('.van-modal').length).to.equal(0);
+ wrapper.vm.overlay = true;
+ setTimeout(() => {
+ expect(testNode.querySelectorAll('.van-modal').length).to.equal(1);
+ done();
+ }, 100);
+ });
+
+ it('popup lock scroll', done => {
+ wrapper = mount(Popup, {
+ propsData: {
+ value: true
+ }
+ });
+
+ setTimeout(() => {
+ expect(document.body.classList.contains('van-overflow-hidden')).to.be.true;
+ done();
+ }, 50);
+ });
});