2

给定以下代码:

<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 退出它,则它可以正常工作。如果您使用箭头键进入选择更改值并退出,它仍然会中断。

4

3 回答 3

0

我的一位同事发现了一个有趣的解决方法:只需添加

elem.parentNode.replaceChild(elem, elem)

设置 tabindex 后使其工作。似乎这种 DOM 操作会触发重新计算 IE 的内部选项卡顺序,否则会丢失。

虽然这总比没有解决方案好,但它是一个相当丑陋的黑客攻击。:-(

如果有人知道不同的、不那么蛮力的解决方案,我仍然会感兴趣。

于 2013-07-10T07:49:25.580 回答
0

在处理 IE 9 中的隐藏单选按钮时,我遇到了类似的问题。我将 tabIndex 设置为 -1,但您仍然可以使用选项卡进入单选组。我的解决方法是更改​​ CSS 可见性属性,这迫使 IE 忽略该组。

隐藏 IE 9 奇怪的选项卡行为的单选按钮:

$radioBtns.attr('tabIndex', -1).css('visibility', 'hidden');

要显示单选按钮并恢复标准选项卡行为:

$radioBtns.removeAttr('tabIndex').css('visibility', '');
于 2014-10-17T18:27:14.697 回答
0

在 JSFiddle 中,更改代码以设置 JavaScript 属性而不是属性似乎有帮助......

  elem.tabIndex = 2;
  // elem.setAttribute("tabIndex", 2);
于 2013-07-09T18:12:45.313 回答