
使用 select2 后,原生 `change` 事件监听器失效,需改用 select2 的 `change.select2` 自定义事件,并确保在初始化后绑定,而非监听原生 `
Select2 并非简单美化原生
要让依赖联动逻辑(如级联下拉)在 Select2 环境中正常工作,必须将事件监听迁移到 Select2 提供的专用事件机制上:change.select2。
✅ 正确做法:绑定 change.select2 事件
在你的 DropDown.add() 方法中,不应再对 elsDependsOn 中的原生
add(options) { const el = document.getElementById(options.target); const $el = $(el); // 获取 jQuery 对象(必需) const elsDependsOn = options.dependsOn.length === 0 ? [] : options.dependsOn.map(id => document.getElementById(id)); const eventFunction = this.createPopulateDropDownFunction(el, elsDependsOn); // ✅ 关键:初始化 Select2,并监听其自定义 change 事件 $el.select2({ width: '300px' }); $el.on('change.select2', () => { eventFunction(); console.log('Selected:', $el.val()); }); // ❌ 移除这行(原生 change 不触发) // targetObject.elsDependsOn.forEach(depEl => depEl.addEventListener("change", eventFunction)); const targetObject = { el, elsDependsOn, func: eventFunction }; this.targets.push(targetObject); return this; }
⚠️ 注意:change.select2 事件仅在用户通过 Select2 ui(点击选项、键盘选择、清空等)显式修改值时触发;程序调用 $el.val(…).trigger(‘change’) 也需手动触发 .trigger(‘change.select2’) 才能同步响应。
? 同时适配原生与 Select2?(可选增强)
若你希望同一套 DropDown 类既能用于原生
// 在 add() 内部判断是否已初始化 Select2 if ($el.data('select2')) { $el.on('change.select2', eventFunction); } else { el.addEventListener('change', eventFunction); }
但更推荐职责分离:为 Select2 场景单独封装一个 DropDownWithSelect2 子类,或统一初始化所有目标
? 补充说明
- Select2 的 change 事件是 namespaced(命名空间化)的,必须写全 change.select2,仅写 change 无效;
- 确保 jQuery 和 Select2 js/css 已正确加载,且 $(el).select2() 调用在 DOM 就绪之后;
- 若需初始值触发联动(如页面加载后默认选中),请在 initialize() 中手动调用 eventFunction(),或对首个下拉框触发一次 $el.trigger(‘change.select2’)。
遵循以上改造,你的级联下拉即可在拥有搜索功能的同时,保持完整的依赖更新逻辑。