`
clue
  • 浏览: 30440 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

IE sucks, mousedown事件与focus行为分析

    博客分类:
  • web
阅读更多
首先这个问题hax也有相关分析,受益良多。

问题描述(如果你只想看结论,可以跳过此部分)
近些时候发现一个bug:在IE下,当ExtJs中的菜单处于显示状态时,点击TextField或TextArea,发现它的emptyText未移除。(emptyText应该在只有为空,并未激活时显示)
然后对此bug进行了调试追踪,发现TextField并未收到focus事件。
继续制作简单模拟场景以定位排除,最终发现:
当在mousedown事件中改变页面焦点目标时,就会发生问题:界面光标已经在text input中了,但并未发出focus事件;当前的document.activeElement不为text input,而是JS中修改的值。
Ext中Menu会自动将焦点设置为自己(实际上是它下面的一个a元素),然后点击页面其它位置时,它会隐藏。
隐藏的元素是无法获得焦点的,从而导致焦点变动。

这是简单的bug重现案例:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>测试 - oldFocusTarget判断</title>
</head>

<body>
<input type="text" id="test" value="init value" /> <a id="sucks" href="#">sucks</a>
<script type="text/javascript">
var text = document.getElementById("test"),
	a = document.getElementById("sucks");
// 监听text focus状态
var handleFocus = function(){
	document.title = "focus! "+new Date();
	text.value = "";
};
var handleBlur = function(){
	document.title = "blur! "+new Date();
	text.value = "empty text";
};
text.attachEvent("onfocus", handleFocus);
text.attachEvent("onblur", handleBlur);

// text点击时更改focus对象
text.attachEvent("onmousedown", function(){
	a.focus();
});
// 最终,text有输入框,但焦点在a上,并且text未触发focus
</script>
</body>
</html>


简单理解
开始一直不能理解,看完hax的分析后才恍然大悟,其实就是焦点状态不同步。

当点击鼠标时(mousedown),IE的UI控件(即hax所说的windows基础控件所模拟的)会获得焦点,但在Dom层(即hax所说的html层)如果有在mousedown事件中修改焦点目标,会使得它与UI控件层失去同步。
这时,UI控件层的焦点是点击的控件,而Dom层则是JS操作聚焦后的元素。
就出现了文本框内有输入符,但Dom层焦点又不在它身上的bug。
如果不在mousedown中处理焦点,是没有任何问题的,为什么修改后就会失去同步呢?

探索深层原因
这里尝试分析IE对UI控件层与Dom层焦点同步的逻辑,目前有了一个猜测:
1. 当鼠标点击时,先记录Dom层焦点(document.activeElement)为oldFocusTarget
2. UI控件层内部处理点击行为 (注:2、3不区分先后次序)
3. Dom层发出mousedown事件,并执行相关事件句柄
4. 如果现在的Dom层焦点与oldFocusTarget一致,则修改Dom层焦点为当前UI控件。

这是一个比较给力的证明(IE6下测试通过):
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>测试 - oldFocusTarget判断</title>
</head>

<body>
<input type="text" id="test" value="init value" /> <a id="sucks" href="#">sucks</a> <a id="f_uck" href="#">f_uck</a>
<script type="text/javascript">
var text = document.getElementById("test"),
	a = document.getElementById("sucks"),
	b = document.getElementById("f_uck");
// 初始focus对象设置为a
a.focus();
// text点击时更改focus对象,但最终改回来
text.attachEvent("onmousedown", function(){
	b.focus();
	a.focus();
});
// text最终还是focus


// 监听事件触发次序,以对照。因为IE中事件句柄后注册先触发,所以这里在最后注册
var sequence = [];
function record(eventName, domName){
	return function(){
		sequence.push(domName + ' ' + eventName);
	}
}
var toTest = ["mousedown", "mouseup", "focus", "blur"], i, n;
for(i=0; i<toTest.length; i++){
	n = toTest[i];
	text.attachEvent("on"+n, record(n, "text"));
	a.attachEvent("on"+n, record(n, "a"));
	b.attachEvent("on"+n, record(n, "b"));
}
// 5秒后弹出记录下来的次序
setTimeout(function(){
	alert(sequence.join("\n"));
}, 5000);

</script>
</body>
</html>

在这个案例中,初始focus对象为a(注意IE中按F5刷新会保留上次focus目标,所以请F6+回车进行刷新)
然后,点击text input后依次触发:
(点击) text mousedown
(b.focus) a blur, b focus
(a.focus) b blur, a focus
(mousedown完成,对比焦点通过) a blur, text focus

可以看到最后还是触发了text focus,而如果将以上代码的初始focus设置(a.focus())注释掉,就会发现text focus不会发出了。

结束
IE sucks...
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    itsucks-0.4.1开源爬虫

    对于更复杂的爬取需求,itsucks可能也支持自定义配置文件,用户可以通过学习其API文档,了解如何编写这些配置文件,进一步定制爬虫行为。 标签中的"spider"一词,暗示了itsucks具备类似蜘蛛的网络遍历能力,它能够...

    IE吸盘「IE Sucks」-crx插件

    使用IE Sucks插件庆祝淘汰前的最后几天。 每当遇到旨在帮助Internet Explorer像老人一样上楼的代码时,我们都会像过去一样发出经典的IE信息栏。 您知道,这意味着您只有更多无用的废话可以破坏您的浏览器,除非这次...

    IE Sucks-crx插件

    IE SUCKS这么糟糕,实际上是有趣的观看失败! IE样式信息条在页面中的障碍码时发光。 无广告! Internet Explorer是一个浏览器的F ****笑话,并字面上持有进步! 在逐步淘汰之前庆祝最终几天,用IE吸收插件。 每当...

    itsucks-0.4.1.zip

    在实际应用中,itSucks可以帮助开发者和数据分析师高效地获取网络上的信息,但同时也需要注意遵守网站的Robots协议,尊重网站的版权,合法合规地使用网络爬虫技术。在进行网络爬取时,理解并遵循这些原则对于保护...

    itsucks开源代码

    爬虫源码,开源 java 很好 强大 可扩展

    大师品软件_Why Software Sucks

    《大师品软件_Why Software Sucks》是一本深入探讨软件设计缺陷和用户体验问题的书籍,由David S. Platt撰写。这本书旨在揭示为什么某些软件在使用过程中让人感到困扰,并提出改善软件设计的策略。作者Platt是一位...

    Why.Software.Sucks

    Any book is the product of a team effort. In this one, I've had an out- standing supporting cast. Everyone at Addison-Wesley understood and got behind the concept of a book for the users of ...

    Atc Sucks-crx插件

    【Atc Sucks-crx插件】是一款针对英文用户的浏览器扩展程序,主要目的是表达用户对“ATC”(可能是某个网站、服务或功能的缩写)的不满情绪。这款插件由开发者创建,用于向用户展示ATC存在的问题,或者提供某种方式...

    信息安全_数据安全_Why_the_role_of_CISO_sucks_and_w.pdf

    信息安全_数据安全_Why_the_role_of_CISO_sucks_and_w 信息安全研究 金融安全 安全人才 安全对抗 法律法规

    Vegandale Sucks-crx插件

    【Vegandale Sucks-crx插件】是一款专为英文用户设计的浏览器扩展程序,主要功能是替换网络上关于“Vegandale”的相关信息,将其转化为“Gentrified Parkdale”。这款插件针对的是那些可能对“Vegandale”这一名称...

    kevingreen.sucks

    在互联网上,".sucks" 域名通常被用来创建一个平台,让人们可以公开讨论他们认为有问题的事物,这种做法在公众人物、品牌或事件引发争议时尤为常见。"kevingreen.sucks" 很可能是针对名为 Kevin Green 的某个人,...

    Smooth Scroll Sucks-crx插件

    【Smooth Scroll Sucks-crx插件】的开发者将用户的需求转化为切实可行的解决方案,通过该插件的安装与激活,用户可以立即体验到页面滚动的快速响应。插件通过禁用平滑滚动特效,恢复了滚轮和触摸板的原始响应,消除...

    your-band-sucks-v2:通过不良专辑封面分享音乐

    【标题解析】:“your-band-sucks-v2”很可能是一个...总的来说,“your-band-sucks-v2”项目融合了JavaScript技术与音乐文化的创新表达,为用户带来了一种独特的音乐分享体验,同时也展示了前端开发的多样性和趣味性。

    itsucks:http

    ItSucks 网络爬虫 描述 这个项目是一个具有下载(和恢复)文件能力的java网络蜘蛛(网络爬虫)。 它还可以使用正则表达式和下载模板进行高度定制。 所有后端功能也可在单独的库中使用。 官网 执照 本地开发使用 将 ...

    rabbit sucks!-crx插件

    【标题】:“rabbit sucks!-crx插件”是一个针对特定网站或应用的浏览器扩展,其主要功能是优化用户界面,提供更加个性化的浏览体验。这个插件的名称可能具有一定的幽默感,暗示它可以帮助用户摆脱某些他们不喜欢的...

    wtf.zip_it

    描述中的“IE sucks =) You should see it )) ”暗示了讨论的主题可能涉及到Internet Explorer(IE)浏览器,用户对它持批评态度,可能因为其已知的性能问题、安全漏洞或不支持现代Web标准。 标签“it”进一步确认...

    DuPont Sucks FTP-开源

    DuPont Sucks FTP(DPS-FTP)是一个开源的FTP客户端工具,专为用户提供便捷的文件传输服务。这个项目的名称“DuPont Sucks FTP”可能源于一种幽默或反讽的表达,暗示它并非由杜邦公司开发,而是由社区驱动的独立项目...

    sucks:用python制作的小CRUD

    标题中的“sucks:用python制作的小CRUD”表明这是一个使用Python编程语言开发的简单创建、读取、更新和删除(Create, Read, Update, Delete,简称CRUD)应用程序。CRUD是数据库操作的基础,是任何数据管理系统的基石...

    why-your-test-suite-sucks

    标题“why-your-test-suite-sucks”暗示了我们讨论的主题是关于测试套件存在的问题以及如何改进它们。测试套件是软件开发过程中的重要组成部分,它确保代码的质量、稳定性和可靠性。然而,当测试套件出现问题时,...

Global site tag (gtag.js) - Google Analytics