JavaScript函数如何为每个元素赋予tabindex编号?

7

我有一个包含许多字段的表单,为每个输入、选择和按钮都设置了tabindex编号。这很有效,但我希望能够通过程序自动实现。

默认的tabindex顺序不正确,因为我有一个两列布局,每列中都有分组。我想按组从上到下进行。我应该如何编写body.onload函数,以便根据包含的div为所有输入、选择和按钮标记分配tabindex编号?例如,对于我想要首先循环的div,所有输入、选择和按钮标记都可以有一个tabindex=1,第二个div中的所有输入、选择和按钮标记都可以有一个tabindex=2,以此类推。

谢谢!

以下是一个简化的示例:

<style>
  .a { display: inline-block;
       width:200px;
       border: 1px solid black;
  }
</style>


<div class="a">
    <div id="Div01" title="these inputs should have tabindex=1">
        <p>Div 01</p>
        <input id="Div01Field1" type="text" value="Me first"/>
        <input id="Div01Field3" type="text" value="Me second"/>
        <input id="Div01Field2" type="text" value="Me third"/>
        <hr>
    </div>
    <div id="Div03" title="these inputs should have tabindex=3">
        <p>Div 03</p>
        <input id="Div03Field1" type="text" value="Me seventh"/>
        <input id="Div03Field2" type="text" value="Me eighth"/>
        <input id="Div03Field3" type="text" value="Me ninth"/>
        <hr>
    </div>
    <div id="Div05" title="these inputs should have tabindex=5">
        <p>Div 05</p>
        <input id="Div05Field1" type="text" value="Me thirteenth"/>
        <input id="Div05Field2" type="text" value="Me fourteenth"/>
        <input id="Div05Field3" type="text" value="Me fifteenth"/>
    </div>
</div>
<div class="a">
    <div id="Div02" title="these inputs should have tabindex=2">
        <p>Div 02</p>
        <input id="Div02Field1" type="text" value="Me fourth"/>
        <input id="Div02Field2" type="text" value="Me fifth"/>
        <input id="Div02Field3" type="text" value="Me sixth"/>
        <hr>
    </div>
    <div id="Div04" title="these inputs should have tabindex=4">
        <p>Div 04</p>
        <input id="Div04Field1" type="text" value="Me tenth"/>
        <input id="Div04Field2" type="text" value="Me eleventh"/>
        <input id="Div04Field3" type="text" value="Me twelfth"/>
        <hr>
    </div>
    <div id="Div06" title="these inputs should have tabindex=6">
        <p>Div 06</p>
        <input id="Div06Field1" type="text" value="Me sixteenth"/>
        <input id="Div06Field2" type="text" value="Me seventeenth"/>
        <input id="Div06Field3" type="text" value="Me eighteenth"/>
    </div>
</div>

1
这可能会有所帮助:https://dev59.com/m3A75IYBdhLWcg3w3NLf - Sudhir Bastakoti
我更喜欢使用普通的JavaScript函数而不是jQuery解决方案。但是,基本上这就是正确的想法。因为div不能像我想象的那样进行tab索引,所以我需要根据它们所包含的div来应用tabindex编号,并设置函数将遵循的div顺序。 - Michael Swarts
tab索引可能会导致页面不太容易访问(用户输入会以无序的方式跳来跳去)。默认的tab索引是按照页面中出现的交互元素顺序排列的。除非你有一个非常好的理由打破这个流程,否则我建议不要设置tab索引。 - zzzzBov
刚刚添加了一份悬赏,如果你感兴趣的话。 :) - Michael Swarts
@zzzzBov:是的,我确实需要,这就是为什么我设置了赏金! - Michael Swarts
显示剩余3条评论
4个回答

6

这是 Mike 代码的更加灵活的版本,它将 tabIndex 设置为 Div id 中使用的数字。当您更改页面结构时,也无需进行任何修改。

任何没有 ID 或者 ID 不符合前缀-数字模式的 DIV 都会被忽略。

<script> "use strict"; // place after </body> tag
  (function TabNumbers (pfx) {
    /* For all divs in the document with an id pfx followed by a number,
       set the tabIndex of all immediate children with tags of INPUT,
       SELECT, or BUTTON to the numeric value */
    pfx = new RegExp ('^' + pfx + '(\\d+)$');  
    for (var divs = document.getElementsByTagName ('div'), 
             el, m, i = divs.length; i--;) { // traverse all divs 
      if ((m = divs[i].id.match (pfx))) { // for those with id Div#
        for (el = divs[i].firstChild; el; 
             el = el.nextSibling) { // Traverse their child nodes
          if (el.tagName === 'INPUT' || el.tagName === 'SELECT' || 
              el.tagName === 'BUTTON') {
              el.tabIndex = +m[1];
          }         
        }
      }
    }
  }) ('Div');  
</script>

经过一些讨论,规范被修改并接受了以下代码:

<script> "use strict"; // place after </body> tag
  (function TabNumbers () {
    var itags = ["INPUT", "SELECT", "BUTTON"]
      , tags
      , tag
      , el  
      , t
      , a
      ;

    while (itags.length) {
      for (tags = document.getElementsByTagName (itags.pop ()), t = tags.length; t--;) {
        el = tag = tags[t];
        while ((el = el.parentNode) && el.tagName) {
          if (el.getAttribute && (a = el.getAttribute ('data-tindex'))) { 
            tag.tabIndex = a;
            break;
          }
        }
      }     
    }
  }) ();    
</script>

在Chrome上进行过测试


如果Div ID的第一部分可以是任何内容而不仅仅是“Div”,那么这个版本对我来说可能会更有帮助。此外,如果函数可以跳过ID结尾不是2位数字序列的Div,则更好。感谢您的帮助! - Michael Swarts
它应该可以,请问您使用的是什么浏览器?这里是一个使用您原始 HTML 示例的 jsFiddle:http://jsfiddle.net/4dhkh/ - HBP
我在让它正常工作方面遇到了困难。我会继续尝试并在找到解决方法后更新您,但目前为止,在主体关闭标记之后粘贴整个代码块似乎没有任何效果。 - Michael Swarts
昨晚意外崩溃了。等我们再次同步后,我们会聊一下的。我完全支持这个课程的想法。 - Michael Swarts
显示剩余5条评论

3
如果像您的示例中一样,容器 Div01 等可以拥有可排序的 ID,那么您可以这样做: JQuery 解决方案:
var groups = $('div[id^="Div"]').sort(function(a,b){
    return (a.id > b.id) ? 1 : -1;
});

groups.find(':input').each(function(idx){
    $(this).prop('tabindex', idx+1);
});

演示地址: http://jsfiddle.net/gaby/sNekS/


或者更加正确的方法),您可以重新排列

,使它们在源中正确排序,并在呈现时仍以左/右组显示(在内部
上使用float:left),而且完全不需要脚本。

演示地址: http://jsfiddle.net/gaby/sNekS/1/


纯JavaScript解决方案将类group添加到Div##元素和类input添加到输入/选择等元素后

var gnodes = document.getElementsByClassName('group'); // find elements with group class - non-sortable
var groups = []; // create empty array to hold groups - sortable
for (var i = 0, l = gnodes.length; i<l; i++){ // place elements in array so we can sort it
    groups.push( gnodes[i] );
}
groups.sort(function(a,b){ // sort the array based on id
    return (a.id > b.id) ? 1 : -1;
});

var counter = 1; // incremental number to define the tabindex
for (var i = 0, l = groups.length; i<l; i++){
    var group = groups[i],
        elements = group.getElementsByClassName('input'); // find all input elements  of this group (must add class to all of them)
    for (var e = 0, len = elements.length; e < len; e++){
        elements[e].setAttribute('tabindex',counter++); // set tabindex
    }
}

演示位于 http://jsfiddle.net/gaby/sNekS/3/


我需要一个纯JS的解决方案。可以实现吗?谢谢! - Michael Swarts
Div的重新排列也不起作用。每一侧的组高度不同,无法对齐。 - Michael Swarts
@Mike,CSS相当强大 ;) 请看一下http://jsfiddle.net/gaby/sNekS/2/,了解如何对齐高度不等的div。 - Gabriele Petrioli
是的,我知道。但我不想让它们对齐。这会导致大量的空白。请记住,我的问题只涉及一个简化的代码片段。 - Michael Swarts
@Mike,好的。这里有一个纯JavaScript解决方案。我在Div##和输入(所有类型)元素上使用类以便于定位。更新了答案并附上了代码。 - Gabriele Petrioli

0
假设您正在使用Prototype(您可能不是),它看起来像这样:
Event.observe(window, 'dom:load', function() {
    var inputs = [$$('#div1 input, #div1 a'), $$('#div2 input')];

    var i = 0;
    inputs.each(function(inputList) {
        inputList.each(function(input) {
            i++;
            input.tabIndex = i;
        });
    });
});

注意:未经测试


0
<script type="text/javascript">
  function TabNumbers() { 
      var t = document.getElementById('Div01').childNodes;
      for (i = 0; i < t.length; i++) { 
          if (t[i].tagName == 'INPUT' || t[i].tagName == 'SELECT' || t[i].tagName == 'BUTTON') {
              t[i].tabIndex = 1;
          }
      }
      var t = document.getElementById('Div02').childNodes;
      for (i = 0; i < t.length; i++) { 
          if (t[i].tagName == 'INPUT' || t[i].tagName == 'SELECT' || t[i].tagName == 'BUTTON') {
             t[i].tabIndex = 2;
          }
      }
      var t = document.getElementById('Div03').childNodes;
      for (i = 0; i < t.length; i++) { 
          if (t[i].tagName == 'INPUT' || t[i].tagName == 'SELECT' || t[i].tagName == 'BUTTON') {
             t[i].tabIndex = 3;
          }
      }
      var t = document.getElementById('Div04').childNodes;
      for (i = 0; i < t.length; i++) { 
          if (t[i].tagName == 'INPUT' || t[i].tagName == 'SELECT' || t[i].tagName == 'BUTTON') {
             t[i].tabIndex = 4;
          }
      }
      var t = document.getElementById('Div05').childNodes;
      for (i = 0; i < t.length; i++) { 
          if (t[i].tagName == 'INPUT' || t[i].tagName == 'SELECT' || t[i].tagName == 'BUTTON') {
             t[i].tabIndex = 5;
          }
      }
      var t = document.getElementById('Div06').childNodes;
      for (i = 0; i < t.length; i++) { 
          if (t[i].tagName == 'INPUT' || t[i].tagName == 'SELECT' || t[i].tagName == 'BUTTON') {
             t[i].tabIndex = 6;
          }
      }
  }
</script>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接