Bootstrap动态下拉菜单:输入框聚焦时保持菜单展开
解决动态生成输入框下拉菜单输入时自动关闭的问题
问题核心是Bootstrap下拉菜单默认会在点击外部元素时触发关闭逻辑,输入框的点击/输入事件会冒泡到父元素,导致下拉收起。针对动态生成的组件,我们可以通过事件委托阻止特定元素触发关闭,并在输入框激活时强制保持下拉展开。
修改后的完整代码
<!doctype html> <html lang="en"> <head> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> </head> <body> <div class="input-group input-group-sm "> <input type="text" class="form-control" aria-label="Text input with segmented dropdown button"> <div class="input-group-append input-group-sm"> <button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> </button> <div class="dropdown-menu"> <input type="text" placeholder="Search.." class="search"> <a class="dropdown-item" data-value="{{Action}}" href="#">Action</a> <a class="dropdown-item" data-value="{{Another action}}" href="#">Another action</a> <a class="dropdown-item" data-value="{{Something else here}}" href="#">Something else here</a> <div role="separator" class="dropdown-divider"></div> <a class="dropdown-item" data-value="{{Separated lin}}" href="#">Separated link</a> </div> </div> </div> <div class="input-group input-group-sm "> <input type="text" class="form-control" aria-label="Text input with segmented dropdown button"> <div class="input-group-append input-group-sm"> <button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> </button> <div class="dropdown-menu"> <input type="text" placeholder="Search.." class="search"> <a class="dropdown-item" data-value="{{Action}}" href="#">Action</a> <a class="dropdown-item" data-value="{{Another action}}" href="#">Another action</a> <a class="dropdown-item" data-value="{{Something else here}}" href="#">Something else here</a> <div role="separator" class="dropdown-divider"></div> <a class="dropdown-item" data-value="{{Separated lin}}" href="#">Separated link</a> </div> </div> </div> <div class="input-group input-group-sm "> <input type="text" class="form-control" aria-label="Text input with segmented dropdown button"> <div class="input-group-append input-group-sm"> <button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> </button> <div class="dropdown-menu"> <input type="text" placeholder="Search.." class="search"> <a class="dropdown-item" data-value="{{Action}}" href="#">Action</a> <a class="dropdown-item" data-value="{{Another action}}" href="#">Another action</a> <a class="dropdown-item" data-value="{{Something else here}}" href="#">Something else here</a> <div role="separator" class="dropdown-divider"></div> <a class="dropdown-item" data-value="{{Separated lin}}" href="#">Separated link</a> </div> </div> </div> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> <script> $(function(){ // 下拉项点击事件 $('.dropdown-item').click(function(e){ e.preventDefault(); e.stopPropagation(); var value = $(this).data('value'); var textElement = $(this).closest('.input-group').find('.form-control'); textElement.val(textElement.val() + value).focus(); }); // 下拉内搜索功能 $(".search").keyup(function(){ var filter = $(this).val().toUpperCase(); var $dropdown = $(this).closest('.dropdown-menu'); $dropdown.find('.dropdown-item').each(function(){ var txtValue = $(this).text().toUpperCase(); $(this).toggle(txtValue.indexOf(filter) > -1); }); }); // 阻止输入框触发下拉关闭 $('body').on('click', '.form-control, .search', function(e) { e.stopPropagation(); }); // 主输入框获得焦点时,展开对应下拉 $('body').on('focus', '.form-control', function(){ $(this).closest('.input-group').find('.dropdown-toggle').dropdown('show'); }); }); </script> </body> </html>
关键修改说明
- 事件委托处理输入框点击:通过
$('body').on('click', '.form-control, .search', ...)阻止输入框的点击事件冒泡,避免触发Bootstrap下拉的关闭逻辑。事件委托确保动态生成的元素也能生效。 - 输入框焦点时展开下拉:监听输入框的
focus事件,找到对应组的下拉按钮,调用dropdown('show')强制展开下拉菜单。 - 优化下拉项选择逻辑:使用
closest('.input-group')替代多层parent(),让DOM查找更健壮,适配动态结构。 - 简化搜索功能:用jQuery的
each()和toggle()替代原生DOM操作,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者Code Guy
相关产品推荐
相关产品推荐

