前言
其实我想记录的不仅仅是如题所写的,不过却是由此引起的。
非正常
如上图所示,我们不需要这个弹框位置变动(读过源码或者一番操作可知
scroll
、resize
俩事件有关),就比如我司目前项目。仅需要固定住,滚动或者拉伸页面,位置还是保持正常样子
正文
思路
先来段废话,其实这个方法也就那么几个,要么把这个组件拷贝出来修改一下,要么就是通过js动态修改。这俩个肯定可以,不过也肯定很挫。一番源码拜读加探索:
通过refs获取到弹框组件,然后先去除scroll
、resize
俩事件监听,然后添加scroll
事件,修改其位置即可
源码
<el-date-picker ref="datePoint" v-model="timeParse">
</el-date-picker>
export default {
data() {
return {
scrollTarget: null,
scrollCallback: null
}
},
mounted() {
function setPosition(popper, reference) {
if (popper.attributes['x-placement'].value === 'bottom-start') {
popper.style.top = `${reference.getBoundingClientRect().top + reference.getBoundingClientRect().height}px`
} else {
popper.style.top = `${reference.getBoundingClientRect().top - popper.getBoundingClientRect().height - 12}px`
}
}
// 监听时间组件的下拉框显隐(因为首次进入未曾渲染,所以得在其渲染出来才可以操作)
this.$watch(
() => {
return this.$refs.datePoint.pickerVisible
},
(val) => {
// 下拉框的dom
const popper = this.$refs.datePoint.picker.$el
// 点击区域的dom,用于参考设置位置
const reference = this.$refs.datePoint.$el
function scrollCallback() {
setPosition(popper, reference)
}
!this.scrollCallback && (this.scrollCallback = scrollCallback.bind(this))
if (val) {
// 滚动目标区域
this.scrollTarget = this.$refs.datePoint.popperJS.state.scrollTarget
// 调用其自身方法去除事件监听(该方法在IIFE之内,在外部无法通过removeEventListener去除监听)
this.$refs.datePoint.popperJS._removeEventListeners()
// 下拉框渲染完毕重设位置,加setTimeout是为简单处理dom渲染,不然一些诸如getBoundingClientRect方法取得值不是渲染之后的
this.$refs.datePoint.picker.$nextTick(function() {
setTimeout(function() {
setPosition(popper, reference)
}, 200)
})
// 通过之前保存的滚动目标区域添加scroll的监听,使得滚动时可以重设位置
this.scrollTarget.addEventListener('scroll', this.scrollCallback);
} else {
// 当然,下拉框去除也得去除监听
this.scrollTarget.removeEventListener('scroll', this.scrollCallback)
}
}
)
}
}
网友评论