场景:
两级弹框,第一级是bootstrap的modal,里面有一个jqgrid,第二级是jqgrid添加记录的弹框
第二级弹框中的textarea在IE9中不能换行,而在chrome中可以
Day 1
bootstrap的modal和jqgrid全部在实验室环境中搭建起来,比较麻烦,先考虑别的办法
因为IE9调试工具太弱了,看看firefox有没有同样的问题
发现firefox中的问题是textarea不能聚焦
以前遇到过不能获得焦点的问题,跟tabindex有关,把tabindex删掉,没作用
发现一级弹框中加了元素级别的textarea样式,删掉,没作用
因为这个框是jqgrid弹出来的,查看jqgrid源码,有没有劫持回车事件,没有
firefox中逐个删除页面元素,发现可以让textarea获得焦点,可能是元素的问题
把一级对话框内中的jqgrid删掉,再用控制台命令添加纯html二级弹框,还是有问题,说明不是jqgrid的问题
考虑到删除元素会改变子元素的样式,可能是样式问题
firefox中删除所有样式,发现可以获得焦点了,是样式问题
逐步缩小范围,发现是一级弹框有一个行内样式所致,删掉后,可以获得焦点了
但是在IE9中仍然不可换行
解决了firefox不能聚焦的问题
Day 2
现在Chrome和Firefox都没问题了,只好硬着头皮用IE9调试了,鉴于昨天的结论,先从样式角度考虑
发现一级弹框去掉所有样式,就可以换行了
但是聚焦不到特定的某一条样式上,怀疑是脏乱的样式加成结果导致CSS解析器出错了
发现在错误的样式下,只要隐藏对话框也是可换行的,可能是浏览器计算位置时出错了
因为bootstrap样式层叠的太多了,既然不知道哪个样式是错的,那就用正确的样式手写生成原来的样子,也是个办法
生成过程中发现其他样式都去掉,display:block;position:fixed;z-index:1030;就能复现问题,可能是浏览器计算z-index错了
用IE9调试工具修改页面源码,就没问题了。因为页面重绘,重新计算了位置,也可能是事件都删掉了
页面太乱了,清理一下,把页面杂乱的标签都删掉,尤其是script片段,没作用
把link标签都删掉,没问题了。应该是某个样式表的问题,定位到是bootstrap.css或ui.jqgrid.css的问题,这两个删一个问题就复现
把一级弹框的所有父元素保留,删除页面中所有其他的html,问题还存在。但是IE9调试工具中点Refresh就没问题了,IE9调试工具不可靠
不能过度依赖调试工具了,得想办法把本地服务器端运行起来,不然剩下的办法只能是实验室环境中把网页重新静态构建起来了
找到一个可行的解决方案,弹出第二级对话框时,把第一级隐藏掉
Day 3
搭建本机环境,把服务器端运行起来
删掉一级弹框中的所有代码,控制台命令弹出二级纯html弹框,没作用
先用控制台命令弹出二级纯html弹框,再在页面点击弹出一级弹框,没作用
控制台命令弹出二级纯html弹框,再控制台命令弹出一级纯html弹框,好了,应该是一级弹框弹出的过程中做了什么
发现是bootstrap的modal('show')这条语句弹出的框有问题
因为IE9不容易跟源码,所以先不看源码,在实验室环境中,造一个一模一样modal,然后二级弹框果然出问题了,并且firefox和chrome都无法获得焦点
实验室环境中复现了问题,问题快解决了
找到bootstrap的modal插件的官方例子,弹出二级弹框,没问题
对比有问题的代码,发现只要modal-body中包含<button>就能复现问题,定位为bootstrap的问题
考虑解决方案,把服务器中的所有button都换成div,还是有问题,而实验室没问题,说明IE9不太稳定
控制台删掉所有的button,结果好了
看看是哪个button影响的,发现总是最后一个button影响的
用补丁方式,先造一个隐藏的button,然后载入时模拟控制台删掉它,没作用。但是控制台删掉它,就有作用,不稳定
不看modal的源码不行了
为了能调试进源码中,换Chrome跟进bootstrap源码,再到IE9看效果
先把modal函数中代码全删了,果然问题没了,然后逐个功能还原,寻找复现问题的临界点
发现enforceFocus这样的方法,是为了强制让对话框获得焦点,感觉就是这个了
把这个方法注掉,没作用,看看实现,就是先解绑一个自定义聚焦事件再绑定这个自定义聚焦事件
在事件中写log,果然点击textarea,就触发这个自定义事件
把事件中把强制获得焦点的代码删掉,好了,这应该就是问题所在了
考虑解决方案,enforceFocus只是进行解绑和绑定事件,而事件是点击textarea时触发的,那就让它只解绑不绑定
分析源码,enforceFocus引用是Modal.prototype中的方法,而Modal是$.fn.modal.constructor,因此是在源码外改的
尽量不动源码,在源码之外加补丁
chrome和firefox在实验室环境中,textarea是不能获得焦点的,但是网站中可以,原因未知
通过覆盖自动聚焦事件,解决了问题
困难
IE9的调试工具太差,Chrome调试工具虽好,但是Chrome没有问题
bootstrap大量的样式名污染的全局空间,每一个元素有大量冗余的层叠样式
很多事件可能是跟样式名相关联的,删了样式名会影响事件
前两天本机环境没有搭建好,只能通过浏览器调试
第三方库用了什么黑魔法,不知道
页面太杂乱,script片段遍布各处,到处是动态加载但不清理的内容
setTimeout乱用,至少二十处setTimeout,js执行过程紊乱
两层弹框,第一级弹框中还能进行内容tab切换,影响因素比较多
项目代码的问题写的太差,互相依赖,很难对功能进行隔离,不能以功能模块为单位进行测试
二级弹框并不是一级弹框的子元素,而是body的子元素,与一级弹框的位置相距很远,从直觉上很难发现有关联
优势
电脑配置不错,两个显示器,16G内存装了虚拟机可以模拟IE8-11,Edge
没有时间压力,没人催我,没有别的项目或会议打断我
服务器端同事配合,没有怀疑我的能力
bootstrap和jqgrid源码不是太烂
这不是一个偶现的bug,没次都能出现,难度降低了不少
误区
其实IE的问题并不是那么多,更多的是可见代码的问题
黑盒试错,不如静下心来跟进源码看看原理
不能过度依赖调试工具的结论
可以通过改动来试错的代码越多,排除假设的机会就越大