element-ui时间选择器位置固定

2019-01-26  本文已影响0人  nymlc

前言

其实我想记录的不仅仅是如题所写的,不过却是由此引起的。

正常
非正常
如上图所示,我们不需要这个弹框位置变动(读过源码或者一番操作可知scrollresize俩事件有关),就比如我司目前项目。仅需要固定住,滚动或者拉伸页面,位置还是保持正常样子

正文

思路

先来段废话,其实这个方法也就那么几个,要么把这个组件拷贝出来修改一下,要么就是通过js动态修改。这俩个肯定可以,不过也肯定很挫。一番源码拜读加探索:
通过refs获取到弹框组件,然后先去除scrollresize俩事件监听,然后添加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)
                }
            }
        )
    }
}
上一篇下一篇

猜你喜欢

热点阅读