layui下拉框应在form.on('select(xxx)')回调中通过data.elem.options[selectedIndex]获取选中option,再用dataset.xxx或getAttribute()读取自定义属性,避免依赖渲染后的dd元素。

layui下拉框如何通过 change 事件拿到选中 option 的自定义属性
layui 的 select 组件本质仍是原生 <select> + <option>,但渲染后 DOM 结构被重写,原始 option 被隐藏,所以不能直接用 selectElement.selectedOptions[0].dataset.xxx——得从 layui 渲染后的下拉项 DOM 入手。
关键点:layui 在渲染时会把 option 上的自定义属性(如 data-id、data-type)**复制到对应下拉菜单里的 dl.layui-anim.layui-anim-upbit dd 元素上**,包括 data-* 和非 data- 属性(如 value、title),但仅限于初始化时已存在的属性。
- 监听
form.on('select(xxx)', callback)事件,回调参数data中只有value和elem(即原始select元素) - 必须用
data.elem找到当前select,再通过其selectedIndex定位原始option,再读取该option的自定义属性 - 不要试图从
dd元素上取——虽然它有,但 layui 不保证属性名大小写、不处理驼峰转换(data-userRole→dataset.userrole),且依赖内部 DOM 结构,不稳定
获取 data-xxx 属性的可靠写法(兼容 layui 2.8+)
在 form.on('select(xxx)') 回调里,用原生 DOM 方式读取:
form.on('select(statusFilter)', function(data){
var selectElem = data.elem;
var selectedIndex = selectElem.selectedIndex;
var optionElem = selectElem.options[selectedIndex];
<p>// 获取 data-id
var id = optionElem.dataset.id;
// 获取 data-extra-info(注意连字符转驼峰)
var extra = optionElem.dataset.extraInfo;
// 获取任意属性,比如自定义的 role="admin"
var role = optionElem.getAttribute('role');
});
- 必须用
selectElem.options[selectedIndex],不能用selectElem.selectedOptions[0](IE 兼容性差) -
dataset只映射data-开头的属性,且自动转为小驼峰;若需原样 key(如data-USER-ID),改用getAttribute('data-USER-ID') - 如果下拉项是动态追加的(比如用
layui.jquery('option').appendTo(...)),要确保在form.render('select')前已写入属性,否则 layui 初始化时不会复制
为什么 data.value 不等于你想要的 ID?
很多人把 value 当作业务 ID,但实际它只是表单提交值。如果你的 option 是这样写的:<option value="1001" data-id="U9923" data-role="editor">张三</option>,那么:
-
data.value === '1001'(来自value属性) -
optionElem.dataset.id === 'U9923'(来自data-id) - 如果没设
value,浏览器默认取textContent,而 layui 的data.value也会随之变成文本内容,极易混淆
所以别依赖 value 存业务标识,明确用 data-id 或其他 data- 属性承载,并在 JS 中统一读取。
动态修改选项后,自定义属性读不到?
layui 不会监听 option 的属性变更。如果你用 JS 动态设置了 option.dataset.tag = 'new',这个改动**不会同步到已渲染的下拉菜单 dd 元素上**,也不会影响后续 form.on 事件里通过 options[selectedIndex] 的读取——因为 option 元素本身确实有了新属性,但 layui 的渲染逻辑只在初始化或 form.render() 时复制一次。
- 动态增删
option后,必须调用form.render('select', 'your-filter')(第二个参数是容器选择器)重新渲染,才能让新option的自定义属性生效 - 单纯改已有
option的dataset,不触发重新渲染也能读到(因为optionElem.dataset是实时的),但 UI 上的下拉项文字/样式不会更新 - 避免在
change回调里反复操作dataset,容易和渲染节奏错位
最稳的方式:所有数据都走 JS 对象管理,下拉框只负责展示和触发事件,属性读取始终基于原始 option 元素,不依赖 layui 渲染后的副本。


















