`
hax
  • 浏览: 964693 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

西方人通常发现不了的一个IE的bug

    博客分类:
  • AJAX
阅读更多
这个问题我大概在一年多以前在某个用到VML的页面中(当时倒是记录了VML的一个严重问题)首次发现了这个Bug。经过一番狗狗之后,也未发现有同样的报告。后来我又逐渐在几种其他非VML的情形下重现了这个奇异的Bug。经过一番探究,我大致推断出了这个bug的原因。不过我一直没有公开发布过这个有趣的问题,只是跟少数同事提到过它。这个bug有个有趣的特点,就是西方人通常不会碰到这个bug。

最近,真懒同学(realazy)在《认识延迟时间为 0 的 setTimeout》一文中举例说明setTimeout的用途。代码大意如下:
$('myButton').onmousedown = function () {
  var input = document.createElement('input');
  input.type = 'text';
  $('myDiv').appendChild(input);
  input.focus();
}

在IE中,新创建的input没有如预期的获得焦点。

如果把input.focus()放在一个setTimeout中延时执行,则就可以获得焦点。

这个例子本身其实并不能证明realazy想要说明的观点,因为他不小心碰到了一个IE的微妙bug。在留言中,Lunatic Sun倒是敏锐的判断出这是IE的bug,只是这个bug的本质不是那么容易认识到,它其实并不是onmousedown本身的bug。

实际上,这是IE的focus机制的bug。

IE中的所有元素其实并不是被凭空绘制出来的,而是统统基于已有的Windows控件之上。除了典型的按钮、下拉菜单等,普通的div其实也是一个textbox控件。

所以IE的HTML focus等实际是被转换为windows控件的focus,于是在IE中存在两种不同层次的focus机制。理想上,HTML的focus应该被同步转换为windows控件的focus,然而IE可怜的代码导致这种转换存在许多bug。我们经常遇到的焦点虚线框丢失的问题其实就是一个例子。

实际上,在上面的例子中,表面上input没有得到焦点,但是其实调用focus()之后,HTML focus确实已经到了新生成的input中,这一点你可以通过document.activeElement来验证,你也可以按tab和shift-tab观察焦点的切换来证明这一点。然而,由于mousedown事件默认会获得控件焦点,所以windows控件focus就跑回了你的按钮上面了。这里出现了windows focus机制和html focus机制的脱节。显然IE在focus上的同步代码实在是太脆弱了。

事实上,IE对焦点的控制似乎本来就不和逻辑。所有的hasLayout元素都能获得焦点!结果一个页面上大部分区域在mousedown之后焦点就不知跑到哪个元素上了——这显然不是我们想要的行为——合乎HTML规范逻辑的行为应该是只有交互控件,如表单控件和A元素等,才能获得焦点。这导致一个典型的用户体验问题:在一个限制高度的可卷动区域中(例如一个长表单),拖动scrollbar,控件焦点就丢失——实际焦点跑到scrollbar所在的元素(例如form元素)上了。最严重的是,body元素一般总会有scrollbar!为了缓解这个问题,微软为body元素打了补丁,使得body上的scrollbar不会抢走焦点。然而IE这个patch打得实在是太烂了,在标准模式下,canvas从body变成了html元素,所以页面scrollbar就到了html元素上,结果bug又回来了!

撇开抢焦点问题,我们回到前面的话题。

既然html focus还是在input元素上,那么当时windows控件焦点到底跑哪里去了?实际上这个焦点跑到了mousedown所发生的对象上。比如如果是一个input按钮,焦点就会在该input按钮实际对应的windows的Button控件上。不过button元素的实现和一般的input不同,所以button元素上的mousedown之后,windows控件焦点实际上会跑到button元素外层的那个元素所对应的windows控件(通常是TextBox控件)中。

如何证明这一点?我过去用过一个调试工具可以显示出每个html控件实际的windows控件,也能查看实际的windows系统焦点。不过现在想不起来那个工具的名称了。搞笑的是,此处还会出现一个非常orz的症状——也就是本文标题所称的“西方人通常发现不了的一个IE的bug”——可以证明这一点。

focus问题 + 西方人通常发现不了。各位是否已经猜到了呢?大家不妨用realazy的那个页面中的第一个按钮来直接实验一把。

我会在下篇blog中继续聊这个话题。
分享到:
评论
19 楼 achun 2008-05-10  
hax 写道
fins 写道
不知道为什么 西方人发现不了


开动脑筋啊。一样使用IE,我们跟西方人有什么区别呢?

还没有明显发现,不过发现如果点鼠标的中建(波轮),selected生效.
还有就是如果出滚动条的话,focus生效(FF也是这样).这个不算BUG吧!也就是特性吧.
18 楼 hax 2008-05-10  
achun 写道
csf177 写道
Win32还有标准控件? 都有什么呀?
难道大家不知道MFC是给VC用的么?
貌似Window Vista以下所有版本 都以win32 API为基础的吧 会随着主题变有什么奇怪

难道有人认为IE是用label套起来布局的?

基本上能写到res资源文件里的都是Win32的标准控件,
res在用c/c++的时候常用,如果你不是c/c++程序员的话,不知道很正常.

LZ说的当然不是什么label套起来,而是说的label的实现有一个更底层的内核在支持,
这个更底层的内核支持着windows的所有GUI上的东东.


因为我本人不是Window编程人员,没有用过c++和delphi进行windows编程,所以这方面的表述可能不准确。但是我的意思大家可以理解,就是Windows本身的GUI编程所使用的体系,比如它有他自己的控件和焦点机制。这跟HTML的元素上的焦点是不同的。而IE现有的layout引擎显然在将HTML焦点转换为Windows焦点的时候出现了许多隐藏的bug。

BTW,还没有人发现我说的那个“西方人通常发现不了”的bug么?它的症状可以非常一目了然的哦。
17 楼 achun 2008-05-10  
csf177 写道
Win32还有标准控件? 都有什么呀?
难道大家不知道MFC是给VC用的么?
貌似Window Vista以下所有版本 都以win32 API为基础的吧 会随着主题变有什么奇怪

难道有人认为IE是用label套起来布局的?

基本上能写到res资源文件里的都是Win32的标准控件,
res在用c/c++的时候常用,如果你不是c/c++程序员的话,不知道很正常.

LZ说的当然不是什么label套起来,而是说的label的实现有一个更底层的内核在支持,
这个更底层的内核支持着windows的所有GUI上的东东.
16 楼 csf177 2008-05-10  
achun 写道
hax 写道
achun 写道

开眼了.
麻烦你告诉我怎么样证明这个.
我记得以前也用spy++之类的东西软件检查过IE的窗口,没有发现是基于已有的Windows控件之上这个说法呀.
刚才我又用SpyLite查看了一下还是只能发现一个Internet Explorer_Server,其他的都查不到句柄呀


很遗憾,偶老年痴呆忘记那个工具的名字了,可能是delphi的某些调试工具。。。
不过我称之为Windows控件或有不确之处,它并不一定就是Win32的标准控件,而可能是mshtml定义的控件,但是一定是遵循那套机制(MFC?)。

与Gecko是从头重写的不同,IE到现在还遗留了IE4时代(更早的不可考了……)的基本架构,有一些bug或曰feature是这种架构固有的。不过据说IE8会完全重写layout引擎。

知道你说的是什么工具了.
早期的delphi中包含的一个工具.名字我也忘了.(好像画了个人头像的,好像是什么医生的,不确定的说)
可以监视进程,窗体,事件等信息的MON工具.
现在的delphi已经没有这个工具了.
考虑IE的内核和windows系统内核的紧密程度.
这套体制应该是个基础了,也就是你说的不是独立的.
因此可以通过考量windows系统的机制来分析问题.
恩.有道理.

Win32还有标准控件? 都有什么呀?
难道大家不知道MFC是给VC用的么?
貌似Window Vista以下所有版本 都以win32 API为基础的吧 会随着主题变有什么奇怪

难道有人认为IE是用label套起来布局的?
15 楼 achun 2008-05-10  
hax 写道
achun 写道

开眼了.
麻烦你告诉我怎么样证明这个.
我记得以前也用spy++之类的东西软件检查过IE的窗口,没有发现是基于已有的Windows控件之上这个说法呀.
刚才我又用SpyLite查看了一下还是只能发现一个Internet Explorer_Server,其他的都查不到句柄呀


很遗憾,偶老年痴呆忘记那个工具的名字了,可能是delphi的某些调试工具。。。
不过我称之为Windows控件或有不确之处,它并不一定就是Win32的标准控件,而可能是mshtml定义的控件,但是一定是遵循那套机制(MFC?)。

与Gecko是从头重写的不同,IE到现在还遗留了IE4时代(更早的不可考了……)的基本架构,有一些bug或曰feature是这种架构固有的。不过据说IE8会完全重写layout引擎。

知道你说的是什么工具了.
早期的delphi中包含的一个工具.名字我也忘了.(好像画了个人头像的,好像是什么医生的,不确定的说)
可以监视进程,窗体,事件等信息的MON工具.
现在的delphi已经没有这个工具了.
考虑IE的内核和windows系统内核的紧密程度.
这套体制应该是个基础了,也就是你说的不是独立的.
因此可以通过考量windows系统的机制来分析问题.
恩.有道理.
14 楼 hax 2008-05-10  
achun 写道

开眼了.
麻烦你告诉我怎么样证明这个.
我记得以前也用spy++之类的东西软件检查过IE的窗口,没有发现是基于已有的Windows控件之上这个说法呀.
刚才我又用SpyLite查看了一下还是只能发现一个Internet Explorer_Server,其他的都查不到句柄呀


很遗憾,偶老年痴呆忘记那个工具的名字了,可能是delphi的某些调试工具。。。
不过我称之为Windows控件或有不确之处,它并不一定就是Win32的标准控件,而可能是mshtml定义的控件,但是一定是遵循那套机制(MFC?)。

与Gecko是从头重写的不同,IE到现在还遗留了IE4时代(更早的不可考了……)的基本架构,有一些bug或曰feature是这种架构固有的。不过据说IE8会完全重写layout引擎。
13 楼 achun 2008-05-10  
raojl 写道


这个还需要验证吗?电脑用多了吧:

  为什么修改WINDOWS主题的时候,所有风格包括IE风格都变了,你以为做主题包这么强啊?不就是修改了底层视窗元素单元设置。

你这解释正好推翻了你的结论呀!
修改WINDOWS主题并不能影响到IE里面页面的显示呀!
12 楼 raojl 2008-05-10  
achun 写道
hax 写道

IE中的所有元素其实并不是被凭空绘制出来的,而是统统基于已有的Windows控件之上。除了典型的按钮、下拉菜单等,普通的div其实也是一个textbox控件。

开眼了.
麻烦你告诉我怎么样证明这个.
我记得以前也用spy++之类的东西软件检查过IE的窗口,没有发现是基于已有的Windows控件之上这个说法呀.
刚才我又用SpyLite查看了一下还是只能发现一个Internet Explorer_Server,其他的都查不到句柄呀



这个还需要验证吗?电脑用多了吧:

  为什么修改WINDOWS主题的时候,所有风格包括IE风格都变了,你以为做主题包这么强啊?不就是修改了底层视窗元素单元设置。
11 楼 achun 2008-05-10  
fins 写道
down click up 这是事件处理的顺序
在down里做一些事情确实危险

例如 alert一个东西 那么click事件 就不能被正确的触发了

补充:
这个说法在上面的例子里是成立的,
不过并不通用,因为有气泡的event模型问题,
click事件会被首先传递出去.
我的意思是说,如果用up事件的话,一定要注意是否仍然要处理click事件,
以及上下文的关系.并不是说这个方法有问题.
10 楼 achun 2008-05-10  
hax 写道

IE中的所有元素其实并不是被凭空绘制出来的,而是统统基于已有的Windows控件之上。除了典型的按钮、下拉菜单等,普通的div其实也是一个textbox控件。

开眼了.
麻烦你告诉我怎么样证明这个.
我记得以前也用spy++之类的东西软件检查过IE的窗口,没有发现是基于已有的Windows控件之上这个说法呀.
刚才我又用SpyLite查看了一下还是只能发现一个Internet Explorer_Server,其他的都查不到句柄呀
9 楼 hax 2008-05-10  
fins 写道
不知道为什么 西方人发现不了


开动脑筋啊。一样使用IE,我们跟西方人有什么区别呢?
8 楼 fins 2008-05-10  
不知道为什么 西方人发现不了
7 楼 hax 2008-05-10  
focus问题 + 西方人通常发现不了。

发现问题了没?

俺是不是有点标题党?
6 楼 fins 2008-05-09  
down click up 这是事件处理的顺序
在down里做一些事情确实危险

例如 alert一个东西 那么click事件 就不能被正确的触发了
5 楼 fins 2008-05-09  
如果把那个button 换成div+ onclick...
就能很好的说明问题了


其实那个例子里 在IE下和FF主要的区别是
在IE里 按钮下按的效果 看不到
但是在其他浏览器里却能

4 楼 longleg 2008-05-09  
以前遇到过你说的问题,当时没有意识到原来是Bug以为自己的方式是错误的,说实话,IE给程序员带来了很多“尝试性的错误”
3 楼 radar 2008-05-09  
错错错!老大好象标题d了吧!
http://realazy.org/lab/settimeout.html
这个页面难道在FF下正常吗?


你把这些处理放到 onmouseup 里不就正常了吗!既然onmouseup 正常,原因也就猜差不多了吧!

----------------------
其实我觉的处理事件应该放到mouseup中,其实操作系统之类的软件都是这样做的. 比如你下压鼠标,然后后悔了,怎么办.移动鼠标,释放鼠标,什么也不干了!
2 楼 radar 2008-05-09  
错错错!老大好象标题d了吧!
http://realazy.org/lab/settimeout.html
这个页面难道在FF下正常吗?


你把这些处理放到 onmouseup 里不就正常了吗!既然onmouseup 正常,原因也就猜差不多了吧!

----------------------
其实我觉的处理事件应该放到mouseup中,其实操作系统之类的软件都是这样做的. 比如你下压鼠标,然后后悔了,怎么办.移动鼠标,释放鼠标,什么也不干了!
1 楼 fins 2008-05-09  
师傅~~~~~~~~~~ 受八戒一拜!!!

你是怎么发现这些的?
看过IE的代码?

哪有这些介绍浏览器低层机制和原理的文章呢?推荐一些资料吧

我自己看代码太累了

相关推荐

    我发现一个IE8的Bug

    标题中的“我发现一个IE8的Bug”提示我们,这个压缩包可能包含有关Internet Explorer 8浏览器的一个已知或新发现的软件缺陷的信息。在描述中,我们只得到了一个指向博客文章的链接,该链接可能提供了关于这个Bug的...

    ie6BUG解决方案

    - **优雅降级**:如果某些效果在IE6下无法完美实现,可以考虑提供一个替代方案,比如使用非透明的背景色或图片,以确保基本功能不受影响。 - **用户教育**:鼓励用户升级到较新版本的浏览器,因为新版本通常有更完善...

    iebug总结jar包

    "iebug总结jar包"是一个专门针对这些问题的资源集合,它包含了处理IE bug的相关资料,特别是针对IE6的解决方案。以下是基于这个主题的详细知识点: 1. **IE6的渲染引擎**:IE6使用的是Trident渲染引擎,它与现代...

    IEbug、IE6页面问题

    IEbug、IE6页面问题、IE6样式问题

    9个最常见IE的Bug及其fix

    在本文中,我们将深入探讨IE6中最为常见的九个Bug,并提供相应的解决方案,帮助Web开发者们解决这个曾经令人头疼的问题。 ### 1. 居中布局问题 在CSS布局中,将一个元素水平居中是最基本的需求之一。通常,通过...

    AD-IEBUG

    标题“AD-IEBUG”可能指的是一个针对Active Directory(AD)和Internet Explorer(IE)的错误或漏洞的调试工具或技术。在这个场景中,“AD”是微软Windows操作系统中的目录服务,用于存储和管理网络资源,而“IE”是...

    ie6-ie7 dom渲染bug demo

    ie6-ie7 dom渲染bug demo

    css常见的bug(ie)

    在IE6中,如果一个浮动元素设置了margin属性,可能会导致实际的外边距比预期的要宽一倍。为了解决这个问题,可以将浮动元素的`display`属性设置为`inline`。 2. **最小高度的处理**: IE6不支持`min-height`属性...

    莫名其妙的IE 3像素Bug

    标题中的“莫名其妙的IE 3像素Bug”指的是在Internet Explorer(IE)浏览器中出现的一种特定的布局问题。这种问题通常发生在网页元素的边缘,尤其是在不同浏览器间存在渲染差异时。IE浏览器由于其独特的渲染引擎,...

    CSS之IE BUG分析与解决

    本文主要探讨了几个常见的CSS在IE浏览器中的BUG及其解决方案。 1. **错误的扩展与min-height** - 在IE6中,设定`height`或`width`为固定值时,如果内容超出这个值,div会自动扩展,而在其他标准浏览器中,div的...

    ie6bug问题解决

    这个压缩包文件"ie6bug"显然专注于解决与IE6相关的技术挑战。下面,我们将深入探讨IE6中的常见问题以及解决策略。 1. **PNG透明度问题**:IE6不支持PNG8和PNG24格式的阿尔法透明度,导致半透明图片显示不正常。解决...

    非常经典的ie bug汇总,页面之王的代表作

    在IE6、IE7的某些模式下,如果设置了文字的宽度和行高,并且高度小于文字的总高度,这些浏览器可能会自动赋予一个比设定值更高的高度,导致元素扩展错误。例如,在标准模式下,`line-height:180%`可能会超出设定的`...

    IE又一个让人吐血的BUG: 关于 table的position 和 select

    标题中的“IE又一个让人吐血的BUG: 关于 table的position 和 select”指的是在Internet Explorer(IE)浏览器中,开发者遇到的一个与HTML表格(table)的定位(position)属性和下拉选择框(select)相关的bug。这个...

    IE8 序号不动bug完美修复新增鼠标放置控件停止效果

    这个bug通常出现在使用JavaScript或jQuery进行动态内容更新时,特别是在涉及到序列号或者计数器等元素时。IE8的DOM(文档对象模型)处理方式与现代浏览器有所差异,可能无法正确识别或更新这些动态变化。修复此问题...

    软件测试BUG清单分析说明

    如果一个BUG不影响任何测试用例,其影响度为0;反之,如果影响的用例数量越多,其影响度评分也就越高。 用户影响度是另一个重要的考量因素,它直接关系到用户体验。根据BUG可能导致的不同后果,我们可以将其分为六...

    解决ie9、ie10本地css加载不上的解决方法实例

    在IT行业中,尤其是在Web开发领域,兼容性问题一直是一大挑战。Internet Explorer(IE)作为曾经的主流...提供的压缩包文件“本地ie9+10加载css样式”应该包含了一个示例,你可以参考这个例子来实践上述解决方案。

    Bug发现提交报告

    在软件开发过程中,Bug发现和提交报告是一项至关重要的工作,它确保了开发团队能准确、高效地定位并修复问题,从而提升软件的质量和用户体验。以下是一份详细的关于如何编写有效的Bug提交报告的知识点: 1. **简洁...

    IE6 PNG图片 BUG

    总之,"IE6 PNG图片 BUG"是前端开发历史上的一个痛点,虽然现在IE6的使用率已经极低,但在支持更广泛的浏览器兼容性时,理解这个问题仍然很重要。随着技术的进步,如今的浏览器已经更好地支持PNG和其他高级特性,但...

    最常见的9种IE_css_bug及fix

    `通常能够轻松实现这一目标,但在IE6中,这种方法却会遇到问题。具体表现为元素并未准确居中,而是出现了偏移或错误定位。 **问题表现**: - IE6对`margin: auto;`的支持并不完善,导致元素未能正确居中。 **解决...

    IE 常见bug 及其fix

    在Web开发领域,Internet Explorer(IE)曾是程序员们的一大挑战,尤其是对于前端开发者来说,因为IE中存在许多特有的bug。这些bug不仅让开发者头疼,还严重影响了开发效率。本篇将详细介绍9个最常见的IE bug及其...

Global site tag (gtag.js) - Google Analytics