ko

同一网页引入两个不同版本jQuery引发的问题

昨天在前端工程遇到一个以前没有想到过的问题

在维护了十多年的主项目上,最近完成了把 Knockout.js 从用户侧前端子工程 acorn 完全移除的工作,原来的要么迁移成 React 实现,要么把自家运营运维侧的工作移到 staff 子工程。在 staff 子工程里目前还有 Knockout.js 的前端页面逻辑和组件,以及一些以前仿照 bootstrap 写的样式和 js 组件,以及基于 jQuery 的日期选择器 datepicker 和时间选择器 timepicker

但昨天发现某个页面一个封了 datepicker 的 input,通过 data-bind=”textInput” 跟 knockout.js 绑定有奇怪的行为。鼠标点选,input 输入框内文本改变,用 $(el).val() 取的值也正常,但 ko 绑定的值不变。如果直接在 input 框里输入,ko 绑定的值就能正常更新

直接 input 输入可以改变 ko 绑定值,说明 ko 绑定没出问题,鼠标点选后 ko 绑定值不变,说明监听机制哪里有问题。因为这一波迁移里把原来多个版本混用的 ko 统一到了 3.x,先查是不是 ko 跨版本有监听事件的变化,ko 官网没说,某 AI 说 ko 3.x 开始还是现代浏览器有啥啥啥事件不再绑定,但尝试手工验证, $(el).trigger("input")$(element).trigger("change") 这些明确说应该有效的,也不能让 ko.observable 的值更新

自己看业务代码和 datepicker 的代码(都是十年前自己写的),git 记录都显示没变啊,调试过程该有的事件都正常触发。把问题代码涉及的链路和表现丢给 Codex GPT-5.4 xhigh,一开始还说需要检查 ko 绑定机制和 vm 初始化顺序,但这些跟之前正常工作时都没变化。后面揪出来在 jinja2 模板层,渲染 HTML 时引入了两次不同版本的 jQuery,在 ko 绑定时用的第一版,后续 datepicker 初始化时关联到第二版,两边 $.event 不通?两套 jQuery 各自维护了自己的事件缓存和 handler 列表,所以 datepicker 库通过第二套 jQuery 发出的事件到不了 ko 在第一套 jQuery 上注册的 handler,而人肉改 input 里的内容走的浏览器原生 DOM 事件,ko 用的那一版 jQuery 有正常监听能生效。最终移除没必要多引入了一次的 jQuery 后,确保 Knockout.js 和 datepicker 使用的是同一版 jQuery 后恢复正常

前端这些诡异的大坑啊,以前为了弥补浏览器能力不足而需要 jQuery 去封装的各种基础能力,现代浏览器都原生支持(主要是选择器和事件触发监听),未来能走原生都走原生吧