搜索框必须置于navbar-collapse内才能在小屏渲染建议列表;下拉被截断需移除父级overflow:hidden并设position:absolute;键盘导航需手动监听arrow键并维护activeindex;移动端应使用mousedown替代click防止失焦。

搜索框必须放在 navbar-collapse 内部,否则小屏下建议列表根本不会渲染
很多人把 <input type="search"> 直接塞在 <nav class="navbar"></nav> 顶层或 <ul class="navbar-nav"></ul> 里,结果在手机上点开折叠菜单后——搜索框不见了,更别说建议列表。这不是隐藏,是 DOM 根本没生成。Bootstrap 的响应式逻辑只对 navbar-collapse 内的子元素生效。
正确结构是:在 <div class="collapse navbar-collapse"> 里,和 <code><ul class="navbar-nav"></ul> 并列放一个 <form></form>,里面套搜索输入框。这样它才能随断点自动收进汉堡菜单,且保有完整事件流。
- 别用
ms-auto包整个<form></form>—— 它会把搜索框推到折叠菜单最右,用户得滚动才能看到 - 推荐加
class="d-flex align-items-center"到<form></form>,让输入框和旁边按钮高度对齐 - 如果想搜索框始终可见(含小屏),就放弃
navbar-collapse,改用position: static+ 手动控制显示,但会失去原生折叠能力
autocomplete 下拉列表被截断?检查父容器的 overflow: hidden 和定位上下文
常见现象:PC 端建议列表正常弹出,一到手机端就只显示半条,或者直接消失。根源几乎全是父级(比如 <nav></nav> 或 <div class="navbar-nav">)设了 <code>overflow: hidden,或者没脱离文档流。
解决方式不是调 z-index,而是让下拉容器脱离当前布局上下文:
- 给下拉
<div class="autocomplete-list"> 加 <code>position: absolute; top: 100%; left: 0; width: 100%,并确保其最近的非static父级是navbar-collapse或body - 绝对不要给
navbar或navbar-collapse设overflow: hidden—— 这是默认行为,会直接砍掉下拉内容 - 若用 Bootstrap 的
dropdown-menu类模拟下拉,需手动绑定data-bs-toggle="dropdown"到输入框,并禁用默认 dropdown 的 toggle 触发逻辑(它不响应input的 focus) - 用
tabindex="-1"给每个建议项设可聚焦状态,避免屏幕阅读器跳过 -
ArrowDown时activeIndex++,超出范围则归零;ArrowUp同理反向 -
Enter或Tab时,把当前activeIndex对应项的文本填入<input>并触发搜索 - 别忘了
blur时清空activeIndex,否则下次聚焦会从旧位置继续 - 所有建议项绑定
mousedown而非click -
mousedown中立刻event.preventDefault(),阻止默认失焦行为 - 再同步设置
input.value = item.textContent并调用input.dispatchEvent(new Event('input'))触发后续逻辑 - 最后手动
input.focus()保持焦点,避免键盘意外收起
键盘导航失效?↑ ↓ Enter 必须手动监听,Bootstrap 不接管 input 内的上下键
鼠标点建议项能工作,但按方向键没反应,这是最常被忽略的可访问性硬伤。Bootstrap 的 dropdown JS 只管菜单按钮的展开/收起,完全不处理 <input> 内部的键盘导航。
你得自己维护一个 activeIndex,并在 keydown 中拦截 ArrowUp/ArrowDown/Enter:
移动端点击建议项丢失?用 mousedown 替代 click 绑定
iOS Safari 下,点建议项时经常出现「刚点下去、输入框就失焦、键盘收起、选项没选上」。这是因为 blur 事件在 click 前触发,DOM 已经开始销毁。
解法很直接,但容易被当成“奇技淫巧”而弃用:
真正难的不是写这几行 JS,而是意识到:移动端的事件顺序和桌面端不同,不能假设 click 总是可靠的。这点在 iOS 上尤其顽固,绕不开。











