Ответ 1
престижность,
Как насчет использования .index?
e.g $(':input:eq(' + ($(':input').index(this) + 1) + ')');
Используя 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: два ответа, предоставленные до сих пор, требуют записи порядкового номера ко всем входным элементам на странице. Как я уже упоминал в комментариях к одному из них, это то, что я уже делаю, и я бы предпочел иметь решение только для чтения, поскольку это будет происходить внутри плагина.
престижность,
Как насчет использования .index?
e.g $(':input:eq(' + ($(':input').index(this) + 1) + ')');
redsquare абсолютно прав, а также отличное решение, которое я также использовал в одном из моих проектов.
Я просто хотел указать, что ему не хватает скобок, так как текущее решение объединяет индекс с 1, а не добавляет их вместе.
Итак, исправленное решение будет выглядеть так:
$(":input:eq(" + ($(":input").index(this) + 1) + ")");
Извините за двойную почту, но я не смог найти способ прокомментировать его сообщение...
Это решение не требует индексов, а также отлично работает с 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 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>
После проверки каждого найденного кода (и наличия проблем между браузерами) я нашел тот, который работает в верхних браузерах. Не удалось использовать предыдущие подпрограммы из-за некоторых странных проблем.
$(document.body).keydown(function(event) {
if(event.keyCode == 13 ) {
$(":input")[$(":input").index(document.activeElement) + 1].focus();
return false;
}
});
Надеюсь, это поможет кому-то другому. Наслаждайтесь.
Вы можете указать каждому элементу формы идентификатор (или уникальное имя класса), который идентифицировал его как элемент формы, а также дал ему индекс. Например:
<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);
Преимущество этого в том, что вы можете пометить любой элемент следующим образом, независимо от местоположения или типа. Вы также можете управлять порядком вашего обхода. Итак, если по какой-либо причине вы хотите пропустить элемент и вернуться к нему позже, вы также можете это сделать.
Вы можете сделать это, чтобы получить полный список элементов формы, которые вы ищете:
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 );
}
Или вы можете использовать атрибут html 'tabindex', который используется для того, когда пользователь нажимает на форму, он переходит к tabindex = "i" в tabindex = "i + 1". Вы можете использовать jQuery, чтобы получить атрибут очень легко. Сделал бы для хорошего возвращения пользователям без включенного javascript.
Я придумал функцию, которая выполняет задание без явного определения индексов:
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>
Вы можете использовать плагин поля jQuery, который позволяет вам это делать.
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];
Это хорошо сработало для меня, и он правильно пропускает скрытые входы:
input_el.nextAll( 'input:visible:first' ).focus();
Все решения, использующие индекс (или nextAll), будут работать только там, где все входы формы являются братьями и сестрами, например. в пределах того же блока <div>
. Следующее обходит это, создавая массив идентификаторов всех видимых, нечитанных входов на странице и выбирает первый после текущего элемента управления, обертывая раунд, если текущий элемент управления является последним на странице.
ids = $(":input:visible:not([readonly])").map(function () { return this.id });
nextId = ids[($.inArray($(this).attr("id"), ids) + 1) % ids.length];
$("#" + nextId).focus();
Использование функции карты делает ее немного более кратким, чем решения, включающие итераторы.