给定以下代码:
<html>
<head>
<script>
function updateTabIndex() {
setTimeout(function() {
var elem = document.getElementById("id1")
elem.setAttribute("tabIndex", 2)
elem.setAttribute("value", "now: tabindex 2")
}, 100)
}
</script>
</head>
<body>
<h1>Weird Behaviour When Changing the tabindex in onchange Handler in Internet
Explorer</h1>
<p><input id="id1" tabindex="-1" value="tabindex: (-1)"/></p>
<p><select tabindex="1" size="1" onchange="updateTabIndex()" onpropertychange="updateTabIndex()">
<option>tabindex 1 - an option</option>
<option>tabindex 1 - another option</option>
</select></p>
<p><input tabIndex="3" value="tabindex 3"/></p>
<h2>Instructions</h2>
<ol>
<li>Open this page in IE. To be precise, the problem is reproducible in
(at least):
<ul>
<li>IE 8, Version 8.0.6001.18702CO on Windows XP and</li>
<li>IE 9, Version 9.0.8112.16421 on Windows 7 Professional, 64 bit</li>
</ul>
<li>Use the <em>mouse</em> to change the value of the select box.</li>
<li>As you can see, the onchange handler is called and changes the tabindex
of the first input element.</li>
<li>If you now tab out of the select box, you can see that the tab order is
adhered to correctly: you go from the select box to the first input element
and then to the last element on the page.</li>
<li>Close the page and open it again.</li>
<li>Click on the third input element and press Shift + Tab to enter the select
box.</li>
<li>Use the down arrow key on the keyboard to change the selected value in the
select box.</li>
<li>Now tab out of the select box.</li>
<li>As you can see, the onchange handler is called, as before (the text in
the first input field has changed).</li>
<li>However, if you tab around now, you will see that the tabindex attribute
is ignored. Instead the order of the elements in the document source is used
as the tab order.</li>
<li>Even if you change the select box value with the mouse now, the tab
order remains broken. To test again, you need to close the page and open
it again or reload it by entering the url bar and pressing enter. Hitting
F5 will not be enough.</li>
</ol>
</body>
</html>
IE ignores the changed tab order when the select box value (which triggers the change to the tabindex attribute) is changed by some keyboard action (arrow keys) but does not ignore the tabindex change when the select box value is changed with the mouse (see关于上面 html 中预期和感知行为的更详细解释)。
为什么 IE 会这样?特别是,为什么使用鼠标和使用按键时的行为不同。是IE的bug吗?现在,我很确定这是 IE 中的一个错误,但当然也有可能我做错了什么,而这恰好在 FF 中按预期工作。
我已经用谷歌搜索了很多,但据我所知,这个错误(如果是一个)直到现在还没有在任何地方报告或讨论过。
一些备注
首先,Firefox 没有表现出这种奇怪的行为。
为了避免被误解,很明显,当我从选择框中跳出时,我将使用 tabindex 3 到达输入,因为 onchange 处理程序中的异步代码可能尚未执行。但在那之后(当第一个输入中的文本发生变化时),我希望建立新的标签顺序。这就是 FF 的行为方式。
似乎每次我使用向上/向下箭头键时 IE 已经触发了 onchange 事件,而不是当我离开选择框时(如 FF 那样)。我不确定这是否与问题有关。
附加奖励:如果您打开 IE 开发人员工具,您将看到在 DOM 中正确设置了 tabIndex 属性,在不使用鼠标更改选择框值时也是如此。但是 tabindex 在四处切换时会被忽略。
我的(天真的)猜测是 IE 保留了 taborder 的内部表示,并且在这种情况下,这种内部表示没有正确重新计算。
更奇怪的是:您可以删除该文件的第 5 行和第 9 行(setTimeout 调用和右花括号),以便不再异步调用 tabindex 更改。然后,如果您使用鼠标输入选择并通过 Tab 退出它,则它可以正常工作。如果您使用箭头键进入选择更改值并退出,它仍然会中断。