前言
其實(shí)我想記錄的不僅僅是如題所寫(xiě)的女揭,不過(guò)卻是由此引起的录肯。
如上圖所示趴腋,我們不需要這個(gè)彈框位置變動(dòng)(讀過(guò)源碼或者一番操作可知
scroll
、resize
倆事件有關(guān))论咏,就比如我司目前項(xiàng)目优炬。僅需要固定住,滾動(dòng)或者拉伸頁(yè)面厅贪,位置還是保持正常樣子
正文
思路
先來(lái)段廢話(huà)蠢护,其實(shí)這個(gè)方法也就那么幾個(gè),要么把這個(gè)組件拷貝出來(lái)修改一下养涮,要么就是通過(guò)js動(dòng)態(tài)修改糊余。這倆個(gè)肯定可以,不過(guò)也肯定很挫单寂。一番源碼拜讀加探索:
通過(guò)refs獲取到彈框組件贬芥,然后先去除scroll
、resize
倆事件監(jiān)聽(tīng)宣决,然后添加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`
}
}
// 監(jiān)聽(tīng)時(shí)間組件的下拉框顯隱(因?yàn)槭状芜M(jìn)入未曾渲染,所以得在其渲染出來(lái)才可以操作)
this.$watch(
() => {
return this.$refs.datePoint.pickerVisible
},
(val) => {
// 下拉框的dom
const popper = this.$refs.datePoint.picker.$el
// 點(diǎn)擊區(qū)域的dom尊沸,用于參考設(shè)置位置
const reference = this.$refs.datePoint.$el
function scrollCallback() {
setPosition(popper, reference)
}
!this.scrollCallback && (this.scrollCallback = scrollCallback.bind(this))
if (val) {
// 滾動(dòng)目標(biāo)區(qū)域
this.scrollTarget = this.$refs.datePoint.popperJS.state.scrollTarget
// 調(diào)用其自身方法去除事件監(jiān)聽(tīng)(該方法在IIFE之內(nèi)威沫,在外部無(wú)法通過(guò)removeEventListener去除監(jiān)聽(tīng))
this.$refs.datePoint.popperJS._removeEventListeners()
// 下拉框渲染完畢重設(shè)位置,加setTimeout是為簡(jiǎn)單處理dom渲染洼专,不然一些諸如getBoundingClientRect方法取得值不是渲染之后的
this.$refs.datePoint.picker.$nextTick(function() {
setTimeout(function() {
setPosition(popper, reference)
}, 200)
})
// 通過(guò)之前保存的滾動(dòng)目標(biāo)區(qū)域添加scroll的監(jiān)聽(tīng)棒掠,使得滾動(dòng)時(shí)可以重設(shè)位置
this.scrollTarget.addEventListener('scroll', this.scrollCallback);
} else {
// 當(dāng)然,下拉框去除也得去除監(jiān)聽(tīng)
this.scrollTarget.removeEventListener('scroll', this.scrollCallback)
}
}
)
}
}