#javascript #jquery #jquery-mobile
#javascript #jquery #jquery-мобильный
Вопрос:
Не могли бы вы рассказать мне, как переместить фокус на следующее поле при нажатии клавиши enter? Я использую dform
плагин (который преобразует JSON в форму).
Я погуглил, но это не работает. Почему мой фокус не перемещается на следующее поле?
JSFiddle: http://jsfiddle.net/5WkVW/1 /
$(document).keypress(function(e) {
if(e.which == 13) {
// Do something here if the popup is open
alert("dd")
var index = $('.ui-dform-text').index(this) 1;
$('.ui-dform-text').eq(index).focus();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<form id="testSuiteConfigurationform" name="testSuiteConfigurationform" method="post" class="ui-dform-form" novalidate="novalidate">
<label class="ui-dform-label">
<h3>Configuration Parameters</h3>
</label>
<div class="ui-dform-div inputDiv">
<fieldset class="ui-dform-fieldset">
<input type="text" id="totalRetryCount" name="totalRetryCount" tabindex="1" onblur="validateElement('Configuration', 'testSuiteConfigurationform','totalRetryCount')" class="ui-dform-text valid">
<legend class="ui-dform-legend">Total Retry Count</legend>
<label for="totalRetryCount" class="checked">✔</label>
</fieldset>
<fieldset class="ui-dform-fieldset">
<input type="text" id="totalRepeatCount" name="totalRepeatCount" tabindex="2" onblur="validateElement('Configuration', 'testSuiteConfigurationform','totalRepeatCount')" class="ui-dform-text">
<legend class="ui-dform-legend">Total Repeat Count</legend>
</fieldset>
<fieldset class="ui-dform-fieldset">
<select id="summaryReportRequired" name="summaryReportRequired" tabindex="3" onblur="validateElement('Configuration', 'testSuiteConfigurationform','summaryReportRequired')" class="ui-dform-select">
<option class="ui-dform-option" value="true">true</option>
<option class="ui-dform-option" value="false">false</option>
</select>
<legend class="ui-dform-legend">Summary Report Required</legend>
</fieldset>
<fieldset class="ui-dform-fieldset">
<select id="postConditionExecution" name="postConditionExecution" tabindex="4" onblur="validateElement('Configuration', 'testSuiteConfigurationform','postConditionExecution')" class="ui-dform-select">
<option class="ui-dform-option" value="ALWAYS">ALWAYS</option>
<option class="ui-dform-option" value="ON_SUCCESS">ON_SUCCESS</option>
</select>
<legend class="ui-dform-legend">Post Condition Execution</legend>
</fieldset>
</div>
</form>
* Примечание (из комментариев): он также должен работать на страницах, на которых не установлены tabindex
значения
Комментарии:
1. Я протестировал свою окончательную версию на всех 4 примерах HTML, и она будет работать практически на любой странице. Он использует пользовательский селектор jQuery, который я добавил. Наслаждайтесь 🙂
Ответ №1:
Это не удается, потому this
что это document
в вашем коде.
Вы хотите использовать индекс текущего сфокусированного элемента ( document.activeElement
), или, если вы используете делегированные события, вы можете убедиться this
, что это текущий элемент.
Эта окончательная версия работает независимо от того, есть tabindexes
они или нет. Он также обтекает:
JSFiddle 1: http://jsfiddle.net/TrueBlueAussie/5WkVW/11 /
JSFiddle 2: http://jsfiddle.net/TrueBlueAussie/5WkVW/12 /
Они оба используют пользовательский селектор jQuery, который я добавляю, вызываемый :focusable
для выбора всех фокусируемых элементов (включая ссылки):
// register jQuery extension
jQuery.extend(jQuery.expr[':'], {
focusable: function (el, index, selector) {
return $(el).is('a, button, :input, [tabindex]');
}
});
$(document).on('keypress', 'input,select', function (e) {
if (e.which == 13) {
e.preventDefault();
// Get all focusable elements on the page
var $canfocus = $(':focusable');
var index = $canfocus.index(this) 1;
if (index >= $canfocus.length) index = 0;
$canfocus.eq(index).focus();
}
});
Вы можете использовать тот же пользовательский селектор в обработчике событий, если хотите. Тогда он будет работать даже с привязочными ссылками (если вы измените событие на нажатие клавиши вместо нажатия клавиши):
например
$(document).on('keydown', ':focusable', function (e) {
Пример со ссылкой: http://jsfiddle.net/5WkVW/15 /
При этом также используется делегированное on
прослушивание keydown
события на document
. Затем он применяет селектор jQuery, а затем применяет функцию к любому соответствующему элементу, который вызвал событие. Это намного эффективнее, поскольку он применяет селектор только во время события (вместо того, чтобы применять несколько обработчиков событий к каждому элементу, соответствующему DOM).
Старые версии ниже:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/5WkVW/3 /
$(document).keypress(function(e) {
if(e.which == 13) {
// Do something here if the popup is open
//alert("dd")
var index = $('.ui-dform-text').index(document.activeElement) 1;
$('.ui-dform-text').eq(index).focus();
}
});
* Примечание: предупреждения могут мешать focus
работе, поэтому используйте console.log
для вывода подобное и просматривайте в окне отладки большинства браузеров (например, инструменты отладки Chrome F12).
Обновление: http://jsfiddle.net/TrueBlueAussie/5WkVW/4 /
Это возвращает к первому элементу из последнего, а также работает с выбором (поведение по умолчанию заблокировано, поэтому вы можете использовать только пробел для открытия или вверх / вниз для выбора параметров.
$('input,select').on('keypress', function (e) {
if (e.which == 13) {
e.preventDefault();
var $next = $('[tabIndex=' ( this.tabIndex 1) ']');
console.log($next.length);
if (!$next.length) {
$next = $('[tabIndex=1]');
}
$next.focus();
}
});
Запрошенная версия «документа»: http://jsfiddle.net/TrueBlueAussie/5WkVW/5 /
$(document).on('keypress', 'input,select', function (e) {
if (e.which == 13) {
e.preventDefault();
var $next = $('[tabIndex=' ( this.tabIndex 1) ']');
console.log($next.length);
if (!$next.length) {
$next = $('[tabIndex=1]');
}
$next.focus();
}
});
Комментарии:
1. Выполнено… Работает на обоих.. Должно работать на чем угодно! 🙂
2. @Gone Coding: я случайно нажал на стрелку и проголосовал против вас, но я только что заметил и не могу изменить это сейчас. Извините за это. Очевидно, я могу удалить его, если сообщение отредактировано, поэтому, если вы хотите сделать тривиальное редактирование, я это сделаю.
3. @Gone Coding: Спасибо, я изменил его.
4. @GoneCoding этот код не работает, когда следующий элемент является отключенным элементом ввода. могу ли я каким-либо образом добавить только «не отключенные» элементы в список «: focusable»??
5. я получил ответ. я просто заменил ‘: input’ на ‘: enabled’, и это сработало! Спасибо!
Ответ №2:
Я создал версию, отличную от jQuery. Итак, только чистый Javascript; https://jsfiddle.net/mm0uctuv/2 /
Javascript:
var inputs = document.querySelectorAll("input,select");
for (var i = 0 ; i < inputs.length; i ) {
inputs[i].addEventListener("keypress", function(e){
if (e.which == 13) {
e.preventDefault();
var nextInput = document.querySelectorAll('[tabIndex="' (this.tabIndex 1) '"]');
if (nextInput.length === 0) {
nextInput = document.querySelectorAll('[tabIndex="1"]');
}
nextInput[0].focus();
}
})
}
HTML:
<form>
Field 1: <input type="text" tabindex="1"><br>
Field 3: <input type="text" tabindex="3"><br>
Field 2: <input type="text" tabindex="2">
</form>
Комментарии:
1. Избегайте использования значений tabindex, превышающих 0. Это затрудняет людям, которые полагаются на вспомогательные технологии, навигацию и управление содержимым страницы. Из MDN Web Docs
Ответ №3:
На верхнем уровне div
добавьте onKeyDown={this.onKeyDown.bind(this)}
и добавьте следующий метод (ES6) в тот же класс, что и div
:
onKeyDown(event) {
if (event.keyCode === 13) {
event.preventDefault()
const inputs =
Array.prototype.slice.call(document.querySelectorAll("input"))
const index =
(inputs.indexOf(document.activeElement) 1) % inputs.length
const input = inputs[index]
input.focus()
input.select()
}
}
Ответ №4:
Это должен сделать следующий код; он использует tabIndex
свойство. Сообщите нам, если это неприемлемо:
$(function() {
$('input').on('keypress', function(e) {
e.which !== 13 || $('[tabIndex=' ( this.tabIndex 1) ']')[0].focus();
});
});
В выпадающем списке уже есть клавиша enter, предназначенная для открытия выпадающего списка.
Чтобы иметь возможность что-то сделать перед переходом к следующему элементу формы, вы можете использовать следующую версию:
$(function() {
$(document).on('keypress', function(e) {
var that = document.activeElement;
if( e.which == 13 ) {
e.preventDefault();
alert( "dd" );
$('[tabIndex=' ( that.tabIndex 1) ']')[0].focus();
}
});
});
Комментарии:
1. можем ли мы изменить ваш код в моем коде? использование документа?
2. например, $(document). нажатие клавиши(function(e) { if(e.which == 13) { // Сделайте что-нибудь здесь, если всплывающее окно открыто alert(«dd») var index = $(‘.ui-dform-text’).index(this) 1; $(‘.ui-dform-text’).eq(index).focus(); } });
3. Конечно, мы можем, давайте посмотрим, что я могу собрать.
4. Это было хорошо (хорошо сделано при обнаружении присутствующего tabindex), но оно не обтекает и не разрешает ввод при выборе.
5. @user2535959 это понятно, это можно сделать, предотвратив поведение по умолчанию при выборе с
e.preventDefault()
помощью . Смотрите мою обновленную версию.
Ответ №5:
Попробуйте следующий код JavaScript, который я изменил из вашей скрипки. Поведение элементов выбора по умолчанию будет расширяться при нажатии клавиши. Знак плюс в начале $(this).attr(«tabindex»)
Преобразует значение текстового атрибута в int.
$(".ui-dform-text").keypress(function(e) {
if(e.which == 13) {
// Do something here if the popup is open
alert($(this).attr("tabindex"));
var index = $(this).attr("tabindex") 1;
$("[tabindex='" index "']").focus();
}
});
Комментарии:
1. К сожалению (если вы следите за комментариями), он также должен работать на страницах без
tabindex
свойств: (
Ответ №6:
В основном это шутка, но вот ванильная версия JS с использованием новейших API, если у вас современный браузер, он должен быть пуленепробиваемым
Вот что происходит:
- Выберите элементы, входные данные и т. Д. (Исключая отключенные, скрытые и т. Д.)
- Используя синтаксис spread, преобразуйте массив (NodeList) в объект (здесь это NodeObject)
- Перебирайте объекты, они же элементы, они же узлы
- Каждая итерация будет передавать текущий элемент (Node) и следующий элемент (nextNode) в функцию со стрелкой.
- Продолжить, если nextNode является элементом
- Затем добавьте событие нажатия клавиши к текущему элементу
- Внутри события:
- Продолжайте, только если была нажата клавиша enter (используя e.key, А НЕ e.keyCode или e.which — которые устарели)
- Остановить отправку формы
- Сфокусируйте следующий элемент
- Если мы можем, выделите текст в следующем узле
И точно так же у вас есть действительно нечитаемый код, который в основном состоит из скобок и функций со стрелками 🙂
// NodeList of applicable inputs, select, button
let NodesArray = document.querySelectorAll(`
#form input:not([disabled])[type]:not([type="hidden"]),
#form select:not([disabled]),
#form button:not([disabled])[type="submit"]
`);
// Spread the array to an object so we can load the next node without
// keeping track of indexes (barf)
(NodesObject => {
// Node and NextNode are Elements.
// You can update and get data if you want
Object.keys(NodesObject).forEach(i => (({ Node, NextNode }) => {
// Break if we dont have a NextNode
if (NextNode === false) return;
Node.addEventListener('keypress', KeyboardEvent => {
// Only continue if event.key was "Enter"
if (KeyboardEvent.key !== "Enter") return;
// Dont submit, thx
KeyboardEvent.preventDefault();
// Do the thing
NextNode.focus();
// Not all elements have a select method
if (typeof NextNode.select === 'function') NextNode.select();
});
})({
Node: NodesObject[i],
NextNode: NodesObject[(parseInt(i) 1)] ?? false
}));
})({ ...NodesArray });
Ответ №7:
это выглядит так же, но я предлагаю что-то простое, возможно, полезное и легкое для запоминания, и это то, что я использую
HTML
<input placeholder="nama">
<input placeholder="email">
<input placeholder="password">
<button>MASUK<button>
js
$('INPUT').keydown( e => e.which === 13?$(e.target).next().focus():"");
Ответ №8:
// Это сработает; добавьте этот код в свою функцию on ready и определите свой родительский элемент, который включает дочерние элементы для фокусировки.
const mainDiv = document.getElementById(`auto-focuser`); //here your parent element you need to focus
const keyDownEvent = (event) => {
if (event.key === "Enter") {
if (event.target.tagName === "TEXTAREA" amp;amp; (event.target.innerHTML !== "" amp;amp; event.target.innerHTML.substr(-1) !== "n"))
return;
if (event.target.attributes.tabindex) {
const nextElm = mainDiv.querySelectorAll(`[tabindex='${parseInt(event.target.attributes.tabindex.value) 1}']`).item(0)
if (nextElm) {
nextElm.focus()
if (nextElm.tagName === "INPUT" || nextElm.tagName === "TEXTAREA") {
nextElm.select()
nextElm.selectionStart = nextElm.selectionEnd = nextElm.value.length;
}
event.preventDefault()
}
}
}
}
mainDiv?.addEventListener('keydown', keyDownEvent);
Ответ №9:
1. сначала = вы должны поместить ‘textbox’ в имя вашего класса при вводе
2.second = указать определенный идентификатор для каждого ввода
затем напишите этот код для выбора этого элемента и перехода к следующему элементу.
Я выбираю каждый элемент по каждому идентификатору и помещаю функцию next() при нажатии клавиши каждого ввода.
function next(event,elem){
if ( event.keyCode == 13)
{
var list = document.getElementsByClassName("textbox");
for (var i=0 ; i<list.length ; i )
{
if (elem.id == list[i].id)
{
var index = i 1;
list[index].focus();
}
}
}
}
аргументы событий используются для нажатия клавиш//
аргументы elem используются для элемента, который мы нажимаем eneter