mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
149 lines
3.5 KiB
JavaScript
149 lines
3.5 KiB
JavaScript
import manager from './popup-manager';
|
|
import context from './popup-context';
|
|
|
|
export default {
|
|
props: {
|
|
// whether to show popup
|
|
value: Boolean,
|
|
// whether to show overlay
|
|
overlay: Boolean,
|
|
// overlay custom style
|
|
overlayStyle: Object,
|
|
// overlay custom class name
|
|
overlayClass: String,
|
|
// whether to close popup when click overlay
|
|
closeOnClickOverlay: Boolean,
|
|
// z-index
|
|
zIndex: [String, Number],
|
|
// prevent touchmove scroll
|
|
preventScroll: Boolean,
|
|
// prevent body scroll
|
|
lockOnScroll: {
|
|
type: Boolean,
|
|
default: true
|
|
}
|
|
},
|
|
|
|
watch: {
|
|
value(val) {
|
|
this[val ? 'open' : 'close']();
|
|
}
|
|
},
|
|
|
|
beforeMount() {
|
|
this._popupId = 'popup-' + context.plusKeyByOne('idSeed');
|
|
context.instances[this._popupId] = this;
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
opened: false,
|
|
pos: {
|
|
x: 0,
|
|
y: 0
|
|
}
|
|
};
|
|
},
|
|
|
|
methods: {
|
|
recordPosition(e) {
|
|
this.pos = {
|
|
x: e.touches[0].clientX,
|
|
y: e.touches[0].clientY
|
|
};
|
|
},
|
|
|
|
watchTouchMove(e) {
|
|
const pos = this.pos;
|
|
const dx = e.touches[0].clientX - pos.x;
|
|
const dy = e.touches[0].clientY - pos.y;
|
|
const direction = dy > 0 ? '10' : '01';
|
|
const el = this.$el.querySelector('.scroller') || this.$el;
|
|
const scrollTop = el.scrollTop;
|
|
const scrollHeight = el.scrollHeight;
|
|
const offsetHeight = el.offsetHeight;
|
|
const isVertical = Math.abs(dx) < Math.abs(dy);
|
|
|
|
let status = '11';
|
|
|
|
if (scrollTop === 0) {
|
|
status = offsetHeight >= scrollHeight ? '00' : '01';
|
|
} else if (scrollTop + offsetHeight >= scrollHeight) {
|
|
status = '10';
|
|
}
|
|
|
|
if (status !== '11' && isVertical && !(parseInt(status, 2) & parseInt(direction, 2))) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}
|
|
},
|
|
|
|
open() {
|
|
if (this.opened || this.$isServer) {
|
|
return;
|
|
}
|
|
|
|
this.$emit('input', true);
|
|
|
|
// 如果属性中传入了`zIndex`,则覆盖`context`中对应的`zIndex`
|
|
if (this.zIndex !== undefined) {
|
|
context.zIndex = this.zIndex;
|
|
}
|
|
|
|
if (this.overlay) {
|
|
manager.openModal({
|
|
id: this._popupId,
|
|
zIndex: context.plusKeyByOne('zIndex'),
|
|
dom: this.$el,
|
|
className: this.overlayClass,
|
|
customStyle: this.overlayStyle
|
|
});
|
|
|
|
if (this.lockOnScroll) {
|
|
document.body.classList.add('van-overflow-hidden');
|
|
}
|
|
}
|
|
|
|
this.$el.style.zIndex = context.plusKeyByOne('zIndex');
|
|
this.opened = true;
|
|
|
|
if (this.preventScroll) {
|
|
document.addEventListener('touchstart', this.recordPosition, false);
|
|
document.addEventListener('touchmove', this.watchTouchMove, false);
|
|
}
|
|
},
|
|
|
|
close() {
|
|
if (!this.opened || this.$isServer) {
|
|
return;
|
|
}
|
|
|
|
this.$emit('input', false);
|
|
|
|
if (this.lockOnScroll) {
|
|
document.body.classList.remove('van-overflow-hidden');
|
|
}
|
|
|
|
this.opened = false;
|
|
this.doAfterClose();
|
|
},
|
|
|
|
doAfterClose() {
|
|
manager.closeModal(this._popupId);
|
|
|
|
if (this.preventScroll) {
|
|
document.removeEventListener('touchstart', this.recordPosition, false);
|
|
document.removeEventListener('touchmove', this.watchTouchMove, false);
|
|
}
|
|
}
|
|
},
|
|
|
|
beforeDestroy() {
|
|
context.instances[this._popupId] = null;
|
|
manager.closeModal(this._popupId);
|
|
if (this.lockOnScroll) {
|
|
document.body.classList.remove('van-overflow-hidden');
|
|
}
|
|
}
|
|
};
|