Safari,我错怪你了~~

Safari,我错怪你了,哦,不对,不是错怪你了,是你bug太多,导致我错误了估计了问题的原因。

昨天要改一个P0的bug,就是Safari上,动态产生的select对象的无法响应鼠标事件,做出下拉动作。开始做了简单的实验,就是用静态HTML写的select对象来测,发现能够响应,估计是Safari动态产生的对象丢失默认事件处理方法。然后又发现,动态产生的select对象可以响应onclick事件,但是响应了就没有其他动作,所以我就捕获onclick然后准备手动打开下拉。先是尝试在onclick事件里focus一把,然后模拟键盘事件。可是想尽一切办法都无法模拟事件,按照W3C标准方法都不行,开始还靠RP蒙对了Safari上创建键盘事件的参数,不是W3C的createEvent("KeyEvents")而是createEvent("KeyboardEvents"),全靠RP啊,没有任何文档和google结果都蒙对了。可当我满怀信心的到dispatch事件时,却发现怎么都不成功,再google,发现了apple的maillist上说他们的Safari没有实现手动事件模拟,faint啊faint,这都没有还敢拿出来当产品!

后来,打算放弃了,准备为Safari自己重新模拟实现一个select控件。今天一来,又做了些别的试验,发现动态创建的select在Safari上是可以drop list的。怪了,难道我的实现有什么特别之处吗?后来看来看去,发现我们为了防止页面内事件的互相影响,在select之上那个div那里停止了click, dbclick, mousedown & mouseup事件的bubble up。然后我就依次尝试取消这些停止动作,终于发现在mousedown事件时取消停止,就可以出现list了。OK,然后又做了若干试验,终于证明了Safari实现上和别的浏览器的不一样,Safari肯定是在mousedown事件抛到DOM树的最顶端再开始绘制select的list的,好吧,为了又不让事件的bubble up影响,又能够让mousedown事件顺利到达最顶端,我在select那里捕获了mousedown事件,然后往event对象塞了个标记,这样在外层准备停止bubble up时先判断是否有标记来实现的。

Safari这个古怪的浏览器,搞得我的实现这么ugly,是不是apple的产品都徒有华丽的外表而已呢,hohoho~~