【问题标题】:Best way to find "next" form input element in jQuery?在 jQuery 中查找“下一个”表单输入元素的最佳方法?
【发布时间】:2008-11-14 15:57:49
【问题描述】:

使用 jQuery,从任意元素开始在页面上查找下一个表单元素的最佳方法是什么?当我说表单元素时,我的意思是 <input>、<select>、<button> 或 <textarea>。

在以下示例中,id为“this”的元素是任意起点,id为“next”的元素是我要查找的元素。相同的答案应该适用于所有示例。

示例 1:

<ul>
 <li><input type="text" /></li>
 <li><input id="this" type="text" /></li>
</ul>

<ul>
 <li><input id="next" type="text" /></li>
</ul>

<button></button>

示例 2:

<ul>
 <li><input id="this" type="text" /></li>
</ul>

<button id="next"></button>

示例 3:

<input id="this" type="text" />
<input id="next" type="text" />

示例 4:

<div>
  <input id="this" type="text" />
  <input type="hidden" />
  <div>
    <table>
      <tr><td></td><td><input id="next" type="text" /></td></tr>
    </table>
  </div>
  <button></button>
</div>

编辑:到目前为止提供的两个答案都需要将序列号写入页面上的所有输入元素。正如我在其中一个的 cmets 中提到的,这就是我已经在做的事情,我更希望有一个只读解决方案,因为这将在插件中发生。

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    赞,

    使用 .index 怎么样?

    例如$(':input:eq(' + ($(':input').index(this) + 1) + ')');

    【讨论】:

    • 这很好用。感谢 redsquare、bobbytek4 和 grault on freenode #jquery 的帮助。
    • 过滤掉禁用的字段 $(":input:not(:disabled):eq(" + ($(":input:not(:disabled)").index(currentElement) + 1 )
    • 我需要添加另一组括号,否则它会在索引上执行字符串连接。结束: $(":input:eq(" + ($(":input").index(this) + 1) + ")");
    • 这很好用,但不应该避免相同的 DOM 遍历吗?我存储了输入列表,例如 var $inputs = $("input, select, etc");然后重用该数组: var $nextInput = $inputs.eq($inputs.index($myElement) + 1);
    • 答案应该包含上面 Sentient 的警告,但也应该包含 ":visible" 因为否则列表将包含隐藏类型的输入字段。
    【解决方案2】:

    redsquare 绝对正确,也是一个很好的解决方案,我也在我的一个项目中使用过。

    我只是想指出他缺少一些括号,因为当前的解决方案是将索引与 1 连接,而不是将它们加在一起。

    所以修正后的解决方案如下:

    $(":input:eq(" + ($(":input").index(this) + 1) + ")");
    

    很抱歉重复发布,但我找不到评论他的帖子的方法...

    【讨论】:

      【解决方案3】:

      此解决方案不需要索引,并且与 tabindex 配合得很好 - 换句话说,它每次都为您提供浏览器在选项卡上为您提供的确切元素,而无需任何额外工作。

      function nextOnTabIndex(element) {
            var fields = $($('form')
                          .find('a[href], button, input, select, textarea')
                          .filter(':visible').filter('a, :enabled')
                          .toArray()
                          .sort(function(a, b) {
                            return ((a.tabIndex > 0) ? a.tabIndex : 1000) - ((b.tabIndex > 0) ? b.tabIndex : 1000);
                          }));
      
      
            return fields.eq((fields.index(element) + 1) % fields.length);
          }
      

      它的工作原理是抓取表单中的所有可选项卡字段(http://www.w3.org/TR/html5/editing.html#focus-management 允许),然后根据 (http://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute) 对字段进行排序以计算出下一个要选项卡的元素。一旦有了它,它就会查看传入的字段在该数组中的位置,并返回下一个元素。

      需要注意的几点:

      • jQuery 似乎支持 jQuery 对象上的 sort(),但我找不到 它在文档中明确显示,因此调用 toArray() 然后 将数组重新包装在 jQuery 对象中。
      • 还有其他字段 可以使用标签,但我将它们排除在外,因为它们不是标准的 表单域。

      我用来测试的代码是(使用 jQuery 1.7):

      <script>
        $(function() {
          $('a[href], button, input, select, textarea').click(function() {
            console.log(nextOnTabIndex($(this)).attr('name'));
          })
        });
      </script>
      
      <form>
        <input type='text' name='a'/>
        <input type='text' name='b' tabindex='1' />
        <a>Hello</a>
        <input type='text' name='c'/>
        <textarea name='d' tabindex='2'></textarea>
        <input id='submit' type='submit' name='e' tabindex='1' />
      </form>
      

      【讨论】:

      • 这几乎是完美的。第二个 filter() 应该是 filter('a, :enabled') 否则选择的 'a[href]' 标签将从数组中删除。除了那个小错误之外,这段代码非常漂亮。
      【解决方案4】:

      在尝试了我能找到的所有代码(并且在浏览器之间遇到问题)之后,我找到了一个在顶级浏览器中工作的代码。由于一些奇怪的问题,无法使用以前的例程。

      $(document.body).keydown(function(event) {
          if(event.keyCode == 13 ) {
              $(":input")[$(":input").index(document.activeElement) + 1].focus();
              return false;
          }
      });
      

      希望这对其他人有所帮助。享受吧。

      【讨论】:

        【解决方案5】:

        您可以这样做来获取您正在寻找的表单元素的完整列表:

        var yourFormFields = $("yourForm").find('button,input,textarea,select');
        

        那么,应该很容易找到下一个元素:

        var index = yourFormFields.index( this ); // the index of your current element in the list. if the current element is not in the list, index = -1
        
        if ( index > -1 && ( index + 1 ) < yourFormFields.length ) { 
        
                            var nextElement = yourFormFields.eq( index + 1 );
        
                            }
        

        【讨论】:

          【解决方案6】:

          您可以为每个表单项指定一个 id(或唯一的类名),将其标识为表单元素并为其指定一个索引。例如:

          <div>
              <input id="FormElement_0" type="text" />
              <input id="FormElement_1" type="text" />
          <div>
          

          然后,如果你想从第一个元素遍历到第二个元素,你可以这样做:

          //I'm assuming "this" is referring to the first input
          
          //grab the id
          var id = $(this).attr('id');
          
          //get the index from the id and increment it
          var index = parseInt(id.split('_')[0], 10);
          index++;
          
          //grab the element witht that index
          var next = $('#FormElement_' + index);
          

          这样做的好处是您可以将任何元素标记为下一个,无论位置或类型如何。您还可以控制遍历的顺序。因此,如果您出于某种原因想要跳过某个元素并稍后再返回,您也可以这样做。

          【讨论】:

          • 感谢您的回复。不幸的是,这正是我想要摆脱的 :) 我正在将我的代码移动到一个插件中,我希望它可以在不破坏用户自己选择的 id 的情况下使用。唯一的类名很有趣,但如果可能的话,我更喜欢“只读”的解决方案。
          • 可以理解。我意识到我提供的解决方案有点“肮脏”。从插件的角度来看,意义不大。
          【解决方案7】:

          或者您可以使用 html 属性“tabindex”,当用户在表单周围进行选项卡时,它会转到 tabindex="i" 到 tabindex="i+1"。您可以使用 jQuery 轻松获取属性。对于没有启用 javascript 的用户来说,这也是一个不错的选择。

          【讨论】:

          • 标签索引不能跳过数字吗?
          【解决方案8】:

          我想出了一个无需明确定义索引即可完成工作的函数:

          function nextInput(form, id) {
              var aInputs = $('#' + form).find(':input[type!=hidden]');
              for (var i in aInputs) {
                  if ($(aInputs[i]).attr('id') == id) {
                      if (typeof(aInputs[parseInt(i) + 1]) != 'undefined') {
                          return aInputs[parseInt(i) + 1];
                      }
                  }
              }
          }
          

          这是一个工作示例。表单标签是为了保持一致。您真正需要的是一个共同的父级,甚至可以只使用 body 标签作为父级(对函数稍作修改)。

          将其粘贴到文件中并使用 firefox / firebug 打开,您会看到它为您的所有示例返回正确的元素:

          <html>
            <head>
              <script src="http://www.google.com/jsapi"></script>
              <script>
                function nextInput(form, id) {
                  var aInputs = $('#' + form).find(':input[type!=hidden]');
                  for (var i in aInputs) {
                    if ($(aInputs[i]).attr('id') == id) {
                      if (typeof(aInputs[parseInt(i) + 1]) != 'undefined') {
                        return aInputs[parseInt(i) + 1];
                      }
                    }
                  }
                }
          
                google.load("jquery", "1.2.6");
                google.setOnLoadCallback(function() {
                  console.log(nextInput('myform1', 'this1'));
                  console.log(nextInput('myform2', 'this2'));
                  console.log(nextInput('myform3', 'this3'));
                  console.log(nextInput('myform4', 'this4'));
                });
              </script>
            </head>
            <body>
              <form id="myform1">
                <ul>
                   <li><input type="text" /></li>
                   <li><input id="this1" type="text" /></li>
                </ul>
                <ul>
                  <li><input id="next1" type="text" /></li>
                </ul>
              </form>
          
              <form id="myform2">
                <ul>
                   <li><input type="text" /></li>
                   <li><input id="this2" type="text" /></li>
                </ul>
                <ul>
                  <li><input id="next2" type="text" /></li>
                </ul>
              </form>
          
              <form id="myform3">
                <input id="this3" type="text" />
                <input id="next3" type="text" />
              </form>
          
              <form id="myform4">
                <div>
                  <input id="this4" type="text" />
                  <input type="hidden" />
                  <div>
                  <table>
                    <tr><td></td><td><input id="next4" type="text" /></td></tr>
                  </table>
                  </div>
                  <button></button>
                </div>
              </form>
            </body>
          </html>
          

          【讨论】:

          • 问题明确指出:、
          • 在给定的示例中,它绝对可以。
          • 确实不假。
          【解决方案9】:

          您可以使用 jQuery 字段插件,它允许您这样做。

          【讨论】:

            【解决方案10】:
            var elementSelector = "input:visible,textarea:visible";
            var nextSibling = $(elementSelector )[$(elementSelector ).index() + 1];
            //$(nextSibling).focus(); possible action
            

            我只是认为上面的解决方案更简单,或者如果你愿意,你可以将它们全部添加到一行中:-)

            var nextSibling = $("input:visible,textarea:visible")[$("input:visible,textarea:visible").index() + 1];
            

            【讨论】:

              【解决方案11】:

              这对我来说效果很好,它正确地跳过了隐藏的输入:

              input_el.nextAll( 'input:visible:first' ).focus();
              

              【讨论】:

                【解决方案12】:

                所有使用 index(或 nextAll)的解决方案仅适用于所有表单输入都是同级的情况,例如在同一个&lt;div&gt; 块内。下面通过在页面上创建一个包含所有可见、非只读输入的 id 数组来解决这个问题,并在当前控件之后挑选出第一个,如果当前控件是页面上的最后一个则回绕。

                ids = $(":input:visible:not([readonly])").map(function () { return this.id });
                nextId = ids[($.inArray($(this).attr("id"), ids) + 1) % ids.length];
                $("#" + nextId).focus();
                

                使用 map 函数使其比涉及迭代器的解决方案更简洁。

                【讨论】:

                • 他似乎没有指定任何条件(例如,readonly、visible)。否则,您还可以查看元素的 tabIndex 属性并以这种方式导航。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-06-14
                • 2012-10-13
                • 2013-08-05
                • 1970-01-01
                • 2010-09-29
                • 2019-10-27
                相关资源
                最近更新 更多