输入框点击出现下拉框。下拉框点击不隐藏下拉框同时出现详情弹窗

本文探讨了如何在大量选项下使用el-popover替代el-select,实现下拉框搜索与详情展示的优化。方法一是通过嵌套popover解决,适合选项较少;方法二是采用虚拟滚动和单个Popover显示详情,适用于选项众多场景。

需求:

实现如下图请添加图片描述

分析:

1.下拉框带搜索,一般情况下使用el-select组件完成,该需求存在的问题是点击选项,不能隐藏下拉框,同时显示详情信息。使用el-select未找到能够实现下拉框不隐藏的方法,因此弃用el-select。
2.抛去搜索下拉框,这个样式很符合el-popover的情况。尝试使用el-popover

实现过程:

方法1
初步思路:
popover1,template是el-input,内容是一个列表循环出的template为p标签的popover2。popover2的内容就是详情。这样就实现了,点击输入框,显示popover1。点击p——popover2的template,就显示了popover2的内容——详情。
适用范围: 选项不多,此写法简单,代码逻辑顺畅。
缺点: 在选项很多的情况下,那么有多少个选项,就会有多少个popover2。就会让页面卡顿,页面元素如下图:
在这里插入图片描述

代码如下:

<el-popover placement="bottom" :show-arrow="false" :width="200" :offset="0" trigger="click" popper-class="xxx">
              <template #reference>
                <el-input v-model="xxx" placeholder="xxx" />
              </template>
              <div class="xxx">
                <el-popover
                  popper-class="xxx"
                  placement="right-start"
                  trigger="click"
                  ref="popoverRef"
                  :show-arrow="false"
                  :width="312"
                  :offset="0"
                   v-for="item in xxx"
                >
                  <template #reference>
                    <p class="xxx">{{ item.zhenshixingming }}</p>
                  </template>
                  <p class="itemTitle">详细信息</p>
                  <p>
                    <span class="detailLabel">真实姓名</span>
                    <span class="detailInfo" style="margin-right: 40px;">{{ item.zhenshixingming }}</span>
                  </p>
                  <p>
                    <span class="detailLabel">员工编号</span>
                    <span class="detailInfo">{{ item.yuangongbianhao }}</span>
                  </p>
                  <p>
                    <span class="detailLabel">手机号码</span>
                    <span class="detailInfo">{{ item.shoujihaoma }}</span>
                  </p>
                  <div class="alert" v-if="xxx">
                    <img src="xxx" align="left" />
                    xxxxxxx
                  </div>
                  <el-button type="primary" size="small" style="float: right;" @click="clickBtn">确认</el-button>
                </el-popover>
              </div>
            </el-popover>

备注: 通过popoverRef.value或el-popover源码可知,popover的显/隐对应方法是show() / hide(),(element-ui应该是doShow() / doHide())。因为确认按钮在popover中,所以点击后popover不会主动隐藏,需要执行popoverRef.value.hide()隐藏。

方法2
初步思路:
方法1的问题是popover2过多,其实popover2作用只是显示一个详情弹窗,且同时只显示1个,那么1个popover,通过传值显示不同信息,就可以达到效果。只有1个popover2,那这个popover2就不能是选项的 -> 就不能通过点击p来触发显示 -> 需要一个元素的动作来触发显示 ==> 使用el-popover的“虚拟出发” -> 所需的触发元素使用el-input(https://element-plus.gitee.io/zh-CN/component/popover.html#%E8%99%9A%E6%8B%9F%E8%A7%A6%E5%8F%91)
适用范围: 选项数据很多。
缺点: 代码逻辑没有方法1那么简单
代码如下:

<el-popover placement="bottom" :show-arrow="false" :width="200" :offset="0" trigger="click" popper-class="xxx">
              <template #reference>
                <el-input v-model="xxx" placeholder="xxx" ref="inputRef" />
              </template>
              <div class="xxx">
                <p class="xxx" v-for="item in xxx" @click="() => clickP(item.id)">{{ item.zhenshixingming }}</p>
              </div>
            </el-popover>
            <el-popover
              popper-class="xxx"
              placement="right-start"
              :show-arrow="false"
              :width="312"
              :offset="0"
              ref="popoverRef"
              :virtual-ref="inputRef"
            >
              <template #reference><p></p></template>
              <p class="itemTitle">详细信息</p>
              <p>
                <span class="detailLabel">真实姓名</span>
                <span class="detailInfo" style="margin-right: 40px;">{{ detailInfo.zhenshixingming }}</span>
              </p>
              <p>
                <span class="detailLabel">员工编号</span>
                <span class="detailInfo">{{ detailInfo.yuangongbianhao }}</span>
              </p>
              <p>
                <span class="detailLabel">手机号码</span>
                <span class="detailInfo">{{ detailInfo.shoujihaoma }}</span>
              </p>
              <div class="alert" v-if="xxx">
                <img src="xxx" align="left" />
                xxxxxxx
              </div>
              <el-button type="primary" size="small" style="float: right;" @click="clickBtn">确认</el-button>
            </el-popover>

备注: 通过popoverRef.value或el-popover源码可知,popover的显/隐对应方法是show() / hide(),(element-ui应该是doShow() / doHide())。
1.在clickP方法中要给detalInfo赋值,且执行popoverRef.value.show()显示详情。
2.因为确认按钮在popover中,所以点击后popover不会主动隐藏,需要执行popoverRef.value.hide()隐藏。

<think>好的,用户想实现点击文本框弹出自定义下拉框点击其他地方隐藏下拉框的效果。我需要分步骤解释如何实现这个功能。首先,我应该考虑HTML结构,然后是CSS样式,最后是JavaScript的事件处理。 首先,HTML部分需要一个文本框和一个下拉框。文本框可以用input元素,下拉框通常用div或ul列表。给它们加上ID以便JavaScript操作。 接下来,CSS方面,下拉框默认要隐藏,设置display:none。当激活时改为display:block或者用visibility属性。可能需要绝对定位,让下拉框在文本框下方显示。 然后是JavaScript,主要处理点击事件。当用户点击文本框时,显示下拉框。这里要注意阻止事件冒泡,否则点击文本框时可能会触发document的点击事件,导致下拉框立刻隐藏。 另外,需要在document上添加点击事件监听器,当点击页面其他区域时隐藏下拉框。但是要排除点击文本框和下拉框本身的情况,否则刚显示出来就被隐藏了。可以通过检查事件目标是否属于这两个元素来实现。 还要考虑事件冒泡的问题,如果下拉框内部有可点击元素,点击它们时事件能冒泡到document,否则也会触发隐藏。所以可能需要在下拉框点击事件里阻止冒泡。 最后,测试一下功能是否正常,点击文本框显示,点击其他地方隐藏同时点击下拉框内部会触发隐藏。 可能还需要处理键盘事件,比如按Tab键切换焦点时,但用户当前的需求可能需要这么复杂。先实现基本功能,如果有需要再扩展。 总结步骤:创建HTML元素,设置CSS样式,编写JavaScript事件处理函数,处理事件冒泡和元素判断。确保各个部分协同工作,实现需求。</think>要实现点击文本框弹出下拉框点击其他区域隐藏的功能,可以通过以下步骤实现(以下为Web前端实现方案): 一、HTML结构 ```html <input type="text" id="myInput" placeholder="点击输入框"> <div id="customDropdown" class="dropdown"> <div class="item">选项1</div> <div class="item">选项2</div> <div class="item">选项3</div> </div> ``` 二、CSS样式 ```css #customDropdown { display: none; /* 默认隐藏 */ position: absolute; border: 1px solid #ddd; max-height: 200px; overflow-y: auto; width: 200px; } .dropdown.active { display: block; /* 显示状态 */ } .item { padding: 8px; cursor: pointer; } .item:hover { background-color: #f5f5f5; } ``` 三、JavaScript逻辑 ```javascript const input = document.getElementById('myInput'); const dropdown = document.getElementById('customDropdown'); // 点击输入框input.addEventListener('click', function(e) { e.stopPropagation(); // 阻止事件冒泡 dropdown.classList.add('active'); }); // 点击文档其他区域 document.addEventListener('click', function(e) { if (e.target !== input && !dropdown.contains(e.target)) { dropdown.classList.remove('active'); } }); // 点击下拉项(可选) document.querySelectorAll('.item').forEach(item => { item.addEventListener('click', function() { input.value = this.textContent; dropdown.classList.remove('active'); }); }); ``` 四、实现原理说明 1. 事件冒泡控制: - 使用`e.stopPropagation()`阻止输入框点击事件向上传递 - 通过`contains()`方法判断点击目标是否属于下拉框区域 2. 状态切换: - 通过CSS类名`active`控制下拉框显隐状态 - 显示时设置`display: block`,隐藏时恢复`display: none` 3. 扩展功能建议: ```javascript // 添加键盘事件支持 input.addEventListener('keyup', function(e) { if (e.key === 'Escape') { dropdown.classList.remove('active'); } }); ``` 五、注意事项 1. 定位问题:确保下拉框的父容器具有相对定位,或使用JavaScript动态计算位置 2. 性能优化:当页面存在多个下拉框时,建议使用事件委托 3. 无障碍访问:可添加ARIA属性提升可访问性 完整示例可在CodePen等在线编辑器运行测试,如需多实例支持,需要将选择器改为class选择并调整相应逻辑。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值