Подтвердить что ты не робот

Лучший способ найти "следующий" элемент ввода формы в jQuery?

Используя 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>

EDIT: два ответа, предоставленные до сих пор, требуют записи порядкового номера ко всем входным элементам на странице. Как я уже упоминал в комментариях к одному из них, это то, что я уже делаю, и я бы предпочел иметь решение только для чтения, поскольку это будет происходить внутри плагина.

4b9b3361

Ответ 1

престижность,

Как насчет использования .index?

e.g $(':input:eq(' + ($(':input').index(this) + 1) + ')');

Ответ 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, похоже, поддерживает sort() для объекта jQuery, но я не могу найти это явно в документации, следовательно, вызов toArray(), а затем rewrapping массив в объекте 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>

Ответ 4

После проверки каждого найденного кода (и наличия проблем между браузерами) я нашел тот, который работает в верхних браузерах. Не удалось использовать предыдущие подпрограммы из-за некоторых странных проблем.

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

Надеюсь, это поможет кому-то другому. Наслаждайтесь.

Ответ 5

Вы можете указать каждому элементу формы идентификатор (или уникальное имя класса), который идентифицировал его как элемент формы, а также дал ему индекс. Например:

<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);

Преимущество этого в том, что вы можете пометить любой элемент следующим образом, независимо от местоположения или типа. Вы также можете управлять порядком вашего обхода. Итак, если по какой-либо причине вы хотите пропустить элемент и вернуться к нему позже, вы также можете это сделать.

Ответ 6

Вы можете сделать это, чтобы получить полный список элементов формы, которые вы ищете:

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 );

                    }

Ответ 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

Все решения, использующие индекс (или nextAll), будут работать только там, где все входы формы являются братьями и сестрами, например. в пределах того же блока <div>. Следующее обходит это, создавая массив идентификаторов всех видимых, нечитанных входов на странице и выбирает первый после текущего элемента управления, обертывая раунд, если текущий элемент управления является последним на странице.

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

Использование функции карты делает ее немного более кратким, чем решения, включающие итераторы.