Whatever:hover:无需JavaScript让IE支持丰富伪类
本文介绍如何使用Whatever:hover脚本在IE6至IE8中实现标准的:hover、:active和:focus伪类支持。通过利用IE特有的Behavior机制,该脚本自动将CSS规则转换为IE可识别的类名切换,无需手动编写JavaScript。文章详细解析了其工作原理、多级菜单的CSS优先级技巧以及性能优化建议,帮助开发者在不依赖JS的情况下提升旧版IE的交互体验。
这一特性非常实用,它允许开发者仅通过CSS即可为表格行(<tr>)等元素添加鼠标悬停(mouseover)时的特殊视觉效果。然而,Internet Explorer(IE)对:hover伪类的支持一直存在局限,具体支持程度取决于用户所使用的IE浏览器版本。
Whatever:hover是一个轻量级脚本,旨在为IE6、IE7和IE8快速且自动地添加对标准:hover、:active和:focus伪类的支持。其第三版进一步引入了Ajax支持,这意味着通过JavaScript动态添加到文档中的任何HTML元素,也能在IE环境中响应:hover、:active和:focus样式。
如果你已经熟悉如何使用Whatever:hover,可以直接前往获取最新版本。对于希望深入了解其原理的读者,请继续阅读下文。
使用方法
只需将Whatever:hover链接到body元素即可。需要注意的是,behavior属性中的URL路径是相对于HTML文件的,这与背景图片地址相对于CSS文件的路径解析方式不同。
body { behavior: url("csshover3.htc"); }
工作原理
所有浏览器都提供了通过JavaScript查询样式表中定义规则或动态插入新规则的方法。通常情况下,IE对不支持的规则会返回“unknown”。例如,“div p:first-child”规则会被转换为“divp:unknown”,而“p a[href]”规则则整体返回为“unknown”。幸运的是,IE将:hover伪类视为支持的样式规则,并会保留其原样。
IE还支持所谓的“行为”(behaviors),这不仅包括动态加载内容或持久数据存储等预定义功能,还包括开发者可以在后缀为.htc或.hta的文件中创建的自定义行为。这些行为通过CSS与HTML节点关联,从而“增强”被指定行为中的样式选择器所选中的节点。
综上所述,该脚本创建一个行为来查找样式表中IE不支持的元素,并通过其他手段“欺骗”受影响元素,使其应用样式表中关联的样式。这个复杂操作包含的步骤大致如下:
- 在所有样式表中搜索IE不支持的:hover伪类规则;
- 插入一条IE支持的新规则(例如带有class名称的规则);
- 最后,设置脚本来切换目标元素的class名称。
通过这种方式,:hover、:active和:focus便得到了IE的支持。作为开发人员,除了包含这个行为文件外,无需进行任何其他操作,所有工作均自动完成。
与第1版和第2版相比,第3版同样支持动态添加的HTML(Ajax)。此外,第1版和第2版在页面加载事件中主动搜索受影响元素,而第3版改为借助表达式(expressions)让节点自行回调。关于这部分细节,你可以阅读带注释的版本以获取更多信息。
示例:菜单效果
:hover的一个常见用途是使用列表创建菜单系统。利用这个行为创建两级菜单系统非常简单。例如,如果你从Suckerfish Dropdown(一个带有下拉菜单的网页,相关描述参见A List Apart的文章)中删除了JavaScript,它仍然能正常工作。
但是,多级菜单需要不同的处理方式。这是因为IE不支持子选择符‘>',而子选择符可以完美地仅显示下级子菜单,而不显示更深层的菜单。
li:hover > ul { /* 在 IE 下无效 */ }
有一种替代方法,仅使用简单的子孙选择符来模拟这种行为(主要针对IE)。还有一种不太成熟的方法是应用多个类定义,但更简单的方法是利用CSS选择符的不同优先级(specificity)。每条CSS规则都有特定的重要等级,该等级可以根据规则中的不同元素简单计算得出。以元素名称为基准值“1”,类、伪类和属性选择符的重要性(权重)为“10”,元素ID为“100”。例如,下面的例子展示了这种权重计算。
ul ul { display:none; }
li:hover ul { display:block; }
这样做生效的原因在于选择符的优先级不同。第一条规则仅包含两个元素名称,因此其权重值(优先级)为2。第二条规则也包含两个元素名称,但:hover伪类的权重值为10,因此总和为12。由于第二条规则的优先级高于第一条,被鼠标滑过的li元素内部的ul将被显示。
那么这对解决>子选择符的问题有何帮助呢?原理是,如果一条权重值为12的规则定义所有子菜单都要显示,我们只需创建一条权重值大于12的规则来隐藏下一级菜单。然后,该菜单又需要另一条优先级更高的规则来显示,如此循环。对于3级导航,所需的CSS代码短得出乎意料:
/* 2 和 13 */
ul ul, li:hover ul ul { display:none; }
/* 12 和 23*/
li:hover ul, li:hover li:hover ul { display:block; }
这种方式无需附加任何类样式即可实现无限级嵌套菜单(4级或更多级需要继续添加更多规则)。
脚本事件的性能优化
现在还剩下一件事需要考虑。.htc文件在所有样式表文件中搜索:hover规则,并根据CSS定义对所有它认为需要用脚本处理悬停效果的元素附加鼠标滑过和移出事件。为了找出这些(受影响的)元素,所有去掉:hover伪类选择到的元素以及被:hover伪类修饰的元素本身,都会被选择并处理。一条类似这样的规则
#menu li:hover ul { ... }
…将被调整成下面这样来查找所有可能需要响应鼠标滑过事件的元素:
#menu li { ... }
显然这会选中整个菜单中的每个<li>元素,并对其中大量不需要鼠标事件(在当前情况下)的元素附加事件。这个问题可以很容易解决,我们可以对包含子菜单的列表元素添加一个类样式,比如“folder”。这样一来,调整(去除:hover)之后的样式规则变成了
#menu li.folder { ... }
…可以高效地直接选中那些真正需要事件的元素。缺点是为了改善脚本性能,你需要添加一个类样式(这个类样式的添加纯粹是为了视觉效果,且放弃了li:hover方式实现菜单的通用性)。但从另一个角度考虑,如果你本来就要用一个类来把这些列表元素与普通元素区分开来,那就无所谓了。
为了直观说明上述问题,请查看综合示例。希望你喜欢。
文件下载及更新说明:
文件下载:
Version 3.11 (:hover, :active and :focus) (:hover, :active 和 :focus) Minified, 2.8K (right click & save) | commented, 9.7K | both, zipped Version 1.42.060206 (:hover and :active) download | view Version 2.02.060206 (1.42 and :focus) download | view 说明:
说明1:如果在使用Whatever:hover的过程中遇到问题,请让我知道!由于第3版比较新,可能会存在一些无法预知的问题。
说明2:确保你的Web服务器将.htc文件按照text/x-component的MIME类型发送。关于这方面的更多信息,可以参阅Aldo的个人博客。如果你的主机支持.htaccess文件,可以添加下面这行代码:
AddType text/x-component .htc
说明3:第三版支持在IE6以上版本中使用:hover和:active,对IE7和IE8还支持:focus。由于表达式(expression)在IE8标准模式下不支持,所以Whatever:hover只在IE8的怪异模式(Quirks Mode)下运行。实际上在IE8标准模式中也根本不需要这个脚本了。
说明4:如果使用这个脚本后网页变慢,请尝试对更加具体的选择符运用:hover伪类,比如添加元素名称、使用元素ID或类名称。例如:“div#someId li.group:hover”,而不要只用“.group:hover”。这能很大程度上减少搜索和解析时间,并减少需要应用的事件。请阅读性能优化部分获取更多信息。
说明5:第2版也支持:focus伪类,仅限于A、INPUT和TEXTAREA元素。但是,由于类似“input:focus”这样的选择符被IE的样式表对象返回为“input:unknown”,脚本将基于这些“unknown”规则来附加获得焦点和失去焦点事件,这个问题同样存在于其他浏览器无法识别的伪类。因此,使用2.0版本时,你无法在IE中对A、INPUT和TEXTAREA元素应用浏览器无法识别的伪类,因为他们统统都会被处理成获得焦点样式。如果你确实需要这个功能,请使用1.4版或者3.0版。
在Naar Voren(一个关于Web开发的德语网站)上,有我用德语写的一篇关于用纯CSS在菜单系统中使用:hover的更详细文章(德语版)。对于不懂德语的网友,可以查看该文章的英文翻译版。
非常感谢Arnoud Berendsen和Martin Reurings提供的创意和支持,感谢Robert Jan Verkade和Naar Voren上的朋友们发表我的文章,还要感谢Eric Meyer对这个脚本给予支持和在他的书里提到我的这个网页(指《Eric Meyer谈CSS(卷2)》第六章——译者注)。
作者:peter ned 原文:whatever:hover
译者:小李刀刀 首发:Whatever:hover – 无需javascript让IE支持丰富伪类
转载请注明出处。 上面的文件,本站打包下载地址
JavaScript将图片转换为Base64编码的两种途径
2026-11-05 16:43:05
怎么在 Vue 或 React 项目中正确集成 animate.js
2026-11-05 10:23:38
JS注册事件:addEventListener基础语法与参数详解
2026-11-05 08:44:56
JSP和JS的区别:运行环境与服务端/客户端职责解析
2026-11-04 23:34:36
pdf.js 官方下载地址:GitHub Release 获取预编译包
2026-11-04 23:07:27
