el-select超出可视范围时自动隐藏下拉框

页面滚动时,当el-select超出可视区域 隐藏下拉框

问题描述:当页面滚动使得el-select组件超出视口时,其下拉框仍然显示在页面上。

阅读完两篇参考文档,又去看看阮老师关于IntersectionObserverAPI的讲解,最终得出的解决方案如下: 通过使用IntersectionObserverAPI,我们可以监听el-select组件的可视状态。一旦组件不可见(即超出视口),我们将手动触发组件的失焦事件,从而收起下拉框。 针对于 el-select位于对话框(Dialog)中的情况。根据对话框的具体使用情况,可以在mounted生命周期钩子中设置监听器,或者去监听对话框的visible属性,并在其变化时进行相关处理。

实现

以下为监听对话框显示值的实现。 首先,我们在模板中为每个el-select添加一个data-index属性,以便能够唯一标识并操作它们(调用blur方法):

html 复制代码
  <div ref="wrapperRef" class="view-container">
    <div v-for="item,index in 10" :key="item" class="select-container">
      <el-select ref="selectRef" :data-index="index" popper-class="select-popper-class" v-model="select[item]" size="small">
        <el-option v-for="item in 10" :key="item" :value="item">{{ item }}</el-option>
      </el-select>
    </div>
  </div>

然后,在Vue组件的watch属性中,我们监听visible(假设这是控制Dialog显示的属性):

js 复制代码
 watch: {
    visible: {
      handler(val) {
        if (val) {
          // 使用$nextTick确保DOM更新完成后执行代码
          this.$nextTick(() => {
            const selectRefs = this.$refs.selectRef
            this.observer = new IntersectionObserver(
              (entries) => {
                entries.forEach((entry) => {
                  const { isIntersecting, target } = entry
                  // isIntersecting表示是否出现在了root区域内
                  if (!isIntersecting) {
                    // 隐藏popover
                    selectRefs[target.dataset.index] && selectRefs[target.dataset.index].blur()
                  }
                })
              },
              {
                root: this.$refs.wrapperRef.$el //  root指定目标元素所在的容器节点(即根元素)注意,容器元素必须是目标元素的祖先节点。
              }
            )
            /**
             * observe的参数是一个 DOM 节点对象。
             * 如果要观察多个节点,就要多次调用这个方法。
             * 在这里使用数组循环方法是因为我循环生成了多个el-select。实际业务中可以具体问题具体考虑
             **/
            selectRefs.forEach(ele=>this.observer.observe(ele.$el)) //观察每一个选择器
          })
        } else {
          this.observer.disconnect() // 关闭观察器
        }
      },
      immediate: true
    }
  },

总结

  • visible属性变为true时,使用$nextTick确保DOM更新完成后执行代码。接着,创建一个IntersectionObserver实例来监听每个el-select元素的可视状态。当任意一个el-select超出视口时(即isIntersectingfalse),我们通过blur()方法关闭其下拉框。
  • 如果visible变为false,表示对话框关闭,我们则断开观察器以避免不必要的性能开销。

注意:在实际应用中,visible可能需要根据具体情况进行替换,以适应不同的显示/隐藏逻辑。

通过上述方法,我们可以有效地解决页面滚动时el-select下拉框未能自动隐藏的问题,提升用户体验。

参考

juejin.cn/post/726605... hellogithub2014.github.io/2019/02/26/... www.ruanyifeng.com/blog/2016/1...

相关推荐
拉不动的猪几秒前
# 关于初学者对于JS异步编程十大误区
前端·javascript·面试
玖釉-5 分钟前
解决PowerShell执行策略导致的npm脚本无法运行问题
前端·npm·node.js
Larcher39 分钟前
新手也能学会,100行代码玩AI LOGO
前端·llm·html
徐子颐1 小时前
从 Vibe Coding 到 Agent Coding:Cursor 2.0 开启下一代 AI 开发范式
前端
小月鸭1 小时前
如何理解HTML语义化
前端·html
jump6801 小时前
url输入到网页展示会发生什么?
前端
诸葛韩信2 小时前
我们需要了解的Web Workers
前端
brzhang2 小时前
我觉得可以试试 TOON —— 一个为 LLM 而生的极致压缩数据格式
前端·后端·架构
yivifu2 小时前
JavaScript Selection API详解
java·前端·javascript
这儿有一堆花2 小时前
告别 Class 组件:拥抱 React Hooks 带来的函数式新范式
前端·javascript·react.js