Bootstrap .modal('hide')在IE11报错:Object.keys参数非对象(MVC5场景)
我之前也碰到过一模一样的IE11兼容性坑,这个SCRIPT5007报错的本质是:IE11对Object.keys()的容错性远低于现代浏览器——当你给它传入null或undefined这类非对象值时,它会直接抛出错误,而Chrome、Firefox等浏览器会默认返回空数组。结合你的场景,问题出在切换模态框时,Bootstrap旧版本的内部逻辑在处理登录模态框的隐藏流程中,意外传入了非对象值给Object.keys(),触发了IE11的报错。
下面是几个经过验证的解决方案,按优先级排序:
1. 升级Bootstrap到兼容IE11的稳定版本
如果你的项目用的是Bootstrap 3.x的早期版本(比如3.0.x到3.3.x之间的旧版),强烈建议升级到Bootstrap 3.4.1(这是Bootstrap 3系列的最终稳定版,修复了大量IE11兼容问题)。升级后,官方已经处理了这类Object.keys()的参数校验问题,大概率能直接解决报错。
2. 调整模态框切换的时机,避免同步操作
不要在打开注册模态框的同时直接调用登录模态框的hide方法,而是等登录模态框完全隐藏完成后,再触发注册模态框的显示。Bootstrap提供了hidden.bs.modal事件,专门用于监听模态框隐藏完成的时机:
// 给登录模态框绑定隐藏完成事件 $('#loginModal').on('hidden.bs.modal', function () { // 确认登录模态框完全隐藏后,再打开注册模态框 $('#registerModal').modal('show'); }); // 点击打开注册按钮时,只触发登录模态框隐藏 $('#openRegisterBtn').click(function (e) { e.preventDefault(); // 阻止默认跳转(如果是链接按钮的话) $('#loginModal').modal('hide'); });
这种方式能避免两个模态框的DOM操作冲突,减少Bootstrap内部处理异常的概率。
3. 修复Bootstrap源码的兼容性(不推荐,仅当无法升级时使用)
如果暂时不能升级Bootstrap,可以找到报错对应的代码位置(bootstrap.min.js第6行第585列),或者用非压缩版的bootstrap.js定位到Object.keys的调用处,给参数添加空对象兜底:
比如把原来的:
Object.keys(a)
改成:
Object.keys(a || {})
这样即使a是null或undefined,也会传入空对象,IE11就不会抛出错误了。不过这种方法需要维护修改后的Bootstrap文件,后续升级容易出问题,所以优先推荐方案1或2。
4. 检查模态框的DOM结构与ID唯一性
IE11对DOM结构的容错率很低,确保你的局部视图中:
- 每个模态框的HTML结构完全符合Bootstrap要求:包含
.modal、.modal-dialog、.modal-content三层结构,没有嵌套错误 - 模态框的ID是唯一的(MVC5局部视图如果多次渲染,可能会重复生成相同ID的模态框,导致jQuery选择器定位异常)
内容的提问来源于stack exchange,提问作者Divyesh brevity

