selectmenu 是 jQuery UI 封装的可定制下拉组件,通过隐藏原生 select 并重绘 UI 实现跨平台样式与行为统一,需引入 jQuery UI 且不可重复初始化,支持 open/close 方法及 HTML 自定义,但存在兼容性短板,新项目推荐 Choices.js 等现代替代方案。

selectmenu 不是原生 HTML 元素,它属于 jQuery UI 的组件,浏览器本身不识别 selectmenu 标签。直接写 <selectmenu> 不会生效,也不会渲染出任何东西。
为什么用 selectmenu 而不是原生 <select>
原生 <select> 在不同系统(macOS/Windows/iOS/Android)上样式和行为差异大,几乎无法统一控制外观、下拉动画、键盘导航逻辑或选项分组样式。而 selectmenu 是 jQuery UI 封装的可替换方案,把 <select> 隐藏后用 <span> + <ul> 重绘 UI,所有 DOM 和事件都可控。
- 必须先引入 jQuery 和 jQuery UI(含
selectmenu模块),否则调用.selectmenu()会报TypeError: $(...).selectmenu is not a function - 不能对已初始化的元素重复调用
.selectmenu(),否则会触发Uncaught Error: cannot call methods on selectmenu prior to initialization - 初始化后,原始
<select>会被设为display: none,所有交互操作实际作用于生成的.ui-selectmenu-button和.ui-selectmenu-menu
如何手动触发 selectmenu 的打开/关闭
原生 <select> 没有 API 控制展开状态,但 selectmenu 提供了 "open" 和 "close" 方法:
$("#mySelect").selectmenu("open");
$("#mySelect").selectmenu("close");
- 调用前确保元素已初始化,比如在
$(document).ready()之后执行 - 如果页面中动态插入新
<select>,需显式调用.selectmenu()初始化,再调用"open" -
"open"不会自动聚焦输入框;如需键盘操作支持,得额外调用.selectmenu("widget").find(".ui-selectmenu-text").focus()
自定义下拉菜单项的 HTML 结构
selectmenu 默认只渲染文本内容,但可通过 option 的 data- 属性 + create 事件注入 HTML:
立即学习“前端免费学习笔记(深入)”;
<option value="1" data-icon="icon-home">首页</option>
然后在初始化时处理:
$("#mySelect").selectmenu({
create: function(event, ui) {
$(this).selectmenu("menuWidget").find("li").each(function() {
const option = $($("#mySelect")[0].options[this.dataset.index]);
const icon = option.data("icon");
if (icon) {
$(this).prepend(<span class="icon " + icon + "></span>);
}
});
}
});
-
menuWidget()返回的是下拉面板的<ul>,不是按钮区域 -
this.dataset.index对应原始<select>中 option 的索引,但仅在 jQuery UI 1.12+ 中可靠;旧版本需用$(this).index()并注意被隐藏的<optgroup>会影响索引 - 不要在
change事件里修改菜单 DOM,此时菜单可能已关闭,修改无效
兼容性与替代建议
jQuery UI 已多年未更新,selectmenu 在现代项目中存在明显短板:不支持 Shadow DOM、无 TypeScript 类型定义、与 React/Vue 等框架集成困难、移动端滚动卡顿明显。
- 若项目已用 jQuery UI,且只需简单定制,
selectmenu仍可用,但务必锁定 jQuery UI 1.12.x 版本(1.13+ 移除了部分内部 API) - 新项目建议改用轻量方案:如
Choices.js(纯 JS,无依赖)、tom-select(支持搜索/多选/远程加载)或手写details/summary+aria-expanded的无障碍方案 - 所有自定义下拉都绕不开一个关键点:必须手动同步
aria-expanded、aria-activedescendant和焦点管理,否则屏幕阅读器无法正确识别状态



















