Как переместить фокус на следующее поле при нажатии enter?

#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, предназначенная для открытия выпадающего списка.

ДЕМОНСТРАЦИЯ JS FIDDLE

Чтобы иметь возможность что-то сделать перед переходом к следующему элементу формы, вы можете использовать следующую версию:

 $(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, если у вас современный браузер, он должен быть пуленепробиваемым

Вот что происходит:

  1. Выберите элементы, входные данные и т. Д. (Исключая отключенные, скрытые и т. Д.)
  2. Используя синтаксис spread, преобразуйте массив (NodeList) в объект (здесь это NodeObject)
  3. Перебирайте объекты, они же элементы, они же узлы
  4. Каждая итерация будет передавать текущий элемент (Node) и следующий элемент (nextNode) в функцию со стрелкой.
  5. Продолжить, если nextNode является элементом
  6. Затем добавьте событие нажатия клавиши к текущему элементу
  7. Внутри события:
    • Продолжайте, только если была нажата клавиша 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