tabIndex属性
围绕表单的可访问性与交互性上,各浏览器都下了很大工夫,比如fieldset与legend等用于增强区域感的元素,for,accessKey,defaultValue,maxlength,tabIndex等用于交互或提示的属性。不过,今天只讲tabIndex。
tabIndex 的用处很简单,就是利用tab键遍历页面的表单元素和链接,按照tabindex的大小决定顺序。虽然微不足道,但细节处见真功夫,这是任何一个WEB应用应当具备的亲用力,保证用户在没有鼠标的情况下(如WAP)仍然可以正常使用。
下面的例子,为了突现tabIndex控制焦点跳转的能力,特意把顺序打乱了。请先选中第一个文本域,然后按tab键观察。
根据这篇文章的介绍,W3C DOM与Netscape仅是把tabIndex添加到有限的几个元素上:a, area, button, input, object, select, textarea,也就是所谓的表单元素与链接。IE4则比它多以下元素: applet, body, div, embed, isindex, marquee, span, table, 与td,到了IE5,几乎所有能渲染的元素都拥有这属性(像br元素就是不能渲染的)。tabIndex的值,根据W3C的规定,范围在0到 32767。
在jQuery的源码中,讲到attr部分提供了一条链接,是专门说明如何用javascript设置获取与移除tabIndex属性,不过已有些日子了,许多主流浏览器都更新了版本。因此我再测试了一次。测试程序见下面的运行框:
tabindex为1的input元素 | IE6 | IE7 | IE8 | FF3.55 | opeta10.10 | Safari4.0 | chrome4.02 |
---|---|---|---|---|---|---|---|
el.tabIndex | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
el.getAttribute("tabindex") | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
el.getAttribute("tabIndex") | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
此表格与《Getting, setting, and removing tabindex values with JavaScript》一文中对应的表格相比,全部为1。
我们再来看当表单元素没有显示地设置tabIndex属性时,tabIndex是否存在,存在的话其默认值是多少。
没有tabIndex的input元素 | IE6 | IE7 | IE8 | FF3.55 | opeta10.10 | Safari4.0 | chrome4.02 |
---|---|---|---|---|---|---|---|
el.tabIndex | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
el.getAttribute("tabindex") | 0 | 0 | 0 | null | null | null | null |
el.getAttribute("tabIndex") | 0 | 0 | 0 | null | null | null | null |
如果测试对象为一个没有显式设置tabIndex属性的div元素呢?在W3C标准中,只有表单元素与链接才能tabIndex属性。
没有tabIndex的div元素 | IE6 | IE7 | IE8 | FF3.55 | opeta10.10 | Safari4.0 | chrome4.02 |
---|---|---|---|---|---|---|---|
el.tabIndex | 0 | 0 | 0 | -1 | -1 | -1 | -1 |
el.getAttribute("tabindex") | 0 | 0 | 0 | null | null | null | null |
el.getAttribute("tabIndex") | 0 | 0 | 0 | null | null | null | null |
我们看这篇文章,标准浏览器的设定其泾渭分明,-1给那些不该拥有它的元素,0是默认分配给那些表单元素与链接,如果用户定义了就返回用户的认定值,即便它是div。
不过在IE中,非表单元素与链接无论tabIndex是否定义都返回0,那么我们怎么知道元素是否已定义过呢?《Getting, setting,……》给出一个非常好的办法。利用getAttributeNode 获取对应的属性节点。在IE中,如果是默认属性或已定义属性,将会返回一个对象,标准浏览器则只有当我们显示地设置这属性时才返回对象,其他一律为null。在IE中,如果是默认属性,没有为其赋值,它有一个特殊的specified ,显示为false,如果赋值了,则为true。标准浏览器没有这东西,也不需要此东西。
//在dojo中有它的运用 //http://trac.dojotoolkit.org/browser/dojo/trunk/_base/html.js var _hasAttr = function(node, name){ var attr = node.getAttributeNode && node.getAttributeNode(name); return attr && attr.specified; // Boolean };
再看为没有tabIndex属性元素赋值的情况el.tabIndex=value就不用说了,肯定行得通,dom 0年代的实现。如果一个元素用setAttribute("tabIndex",3)赋值,注意是大写,那么无论是el.tabIndex还是el.getAttribute("tabIndex")还是el.getAttribute("tabindex")都能得到3。如果是setAttribute("tabindex",3)赋值,IE则全为0,标准浏览器则全为3,因此还是用前者吧。
没有tabIndex的input元素 | IE6 | IE7 | IE8 | FF3.55 | opeta10.10 | Safari4.0 | chrome4.02 |
---|---|---|---|---|---|---|---|
el.tabIndex=3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |
el.setAttribute("tabIndex",3) | 3 | 3 | 3 | 3 | 3 | 3 | 3 |
el.setAttribute("tabindex",3) | 0 | 0 | 0 | 3 | 3 | 3 | 3 |
最后移除属性的情况,移除结果后分别用el.tabIndex,el.getAttribute("tabIndex"),el.getAttribute("tabindex")测试。谁都没有把握移除干净,从目前的情况来看,只有选择el.removeAttribute
tabIndex为3的input元素 | IE6 | IE7 | IE8 | FF3.55 | opeta10.10 | Safari4.0 | chrome4.02 |
---|---|---|---|---|---|---|---|
el.removeAttribute |
0,0,0 | 0,0,0 | 0,0,0 | 0,null,null | 0,null,null | 3,null,null | 3,null,null |
el.removeAttribute |
3,3,3 | 3,3,3 | 3,3,3 | 0,null,null | 0,null,null | 3,null,null | 3,null,null |
delete el.tabIndex | errer | errer | errer | 3,3,3 | 0,null,null | 3,3,3 | undefined,null,null |