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

前言

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

正常

非正常

如上图所示,我们不需要这个弹框位置变动(读过源码或者一番操作可知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)
                }
            }
        )
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Vue-Music 一| 前期工作 1.项目初始化 npm install -g vue-cli vue init...
    noobakong阅读 1,889评论 0 5
  • 谢谢作者的文章 非常喜欢 请允许收藏! 博客园首页博问闪存新随笔订阅管理 vue之better-scroll的封装...
    peng凯阅读 16,602评论 2 5
  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,581评论 1 11
  • 除了一些基础的组件,几个列表组件让我非常好奇。所以这里来学习一下 loadmore infinite scroll...
    VioletJack阅读 2,311评论 0 0
  • 假如你经常读书,而且让周遭的人注意到了这一点,那么每逢寒假暑假和“世界读书日”之类的好时候,勤勤恳恳的学生会干部,...
    拉撒路的口袋阅读 170评论 1 0