
使用 select2 后原生 `change` 事件监听失效,是因为 select2 将原始 `
当为
✅ 正确做法是: 监听 Select2 自定义事件,并在回调中显式调用你的业务逻辑函数(如 eventFunction()),同时手动触发原生 change 事件以保持与现有代码的兼容性 。
以下是适配 Select2 的关键修改步骤:
1. 初始化 Select2 并监听自定义事件
在 add() 方法中,完成 Select2 初始化后,替换原生事件绑定逻辑:
add(options) {const el = document.getElementById(options.target); const $el = $(el); // 转为 jQuery 对象(Select2 依赖 jQuery)// 初始化 Select2(可选配置)$el.select2({width: '300px', placeholder: ` 请选择 ${options.target}`, allowClear: true }); const elsDependsOn = options.dependsOn.length === 0 ? [] : options.dependsOn.map(id => document.getElementById(id)); const eventFunction = this.createPopulateDropDownFunction(el, elsDependsOn); // ✅ 关键:监听 Select2 事件,而非原生 change $el.on('select2:select select2:unselect', () => {eventFunction(); // 执行级联逻辑 el.dispatchEvent(new Event('change', { bubbles: true})); // 兼容原生监听器 }); // ❌ 移除这行(原生 change 不再被触发)// targetObject.elsDependsOn.forEach(depEl => depEl.addEventListener("change", eventFunction)); this.targets.push({el, elsDependsOn, func: eventFunction}); return this; }
2. 确保依赖项也启用 Select2(如需搜索功能)
若 level1、level2 等都需要搜索能力,应在 initialize() 或 eazyDropDown() 中统一初始化:
initialize() { this.targets.forEach(t => {const $el = $(t.el); if (!$el.data('select2')) {$el.select2({ width: '300px'}); } }); // 首次填充数据 this.targets.forEach(t => t.func()); return this; }
3. 注意事项与最佳实践
- jQuery 版本兼容性 :Select2 v4+ 要求 jQuery ≥ 1.8;你当前引入的是 3.2.1,完全兼容。
- 事件冒泡 :dispatchEvent() 中设置 { bubbles: true} 可确保事件能被父级委托监听捕获。
- 禁用状态处理 :level4–level7 默认 disabled,初始化 Select2 后仍保持禁用,无需额外处理。
- 性能优化 (可选):对高频触发场景(如快速切换),可在 eventFunction 内加防抖(debounce),避免重复渲染。
总结
Select2 并非“增强”原生