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...

相关推荐
以对_3 分钟前
uview表单校验不生效问题
前端·uni-app
程序猿小D1 小时前
第二百六十七节 JPA教程 - JPA查询AND条件示例
java·开发语言·前端·数据库·windows·python·jpa
奔跑吧邓邓子1 小时前
npm包管理深度探索:从基础到进阶全面教程!
前端·npm·node.js
前端李易安2 小时前
ajax的原理,使用场景以及如何实现
前端·ajax·okhttp
汪子熙2 小时前
Angular 服务器端应用 ng-state tag 的作用介绍
前端·javascript·angular.js
Envyᥫᩣ2 小时前
《ASP.NET Web Forms 实现视频点赞功能的完整示例》
前端·asp.net·音视频·视频点赞
Мартин.6 小时前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss
昨天;明天。今天。8 小时前
案例-表白墙简单实现
前端·javascript·css
数云界8 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd8 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome