64


30

Enterキーを押すとページの「next」フォーム要素にフォーカスが移動するようなフォームを作成しようとしています。 私がウェブ上で見つけ続ける解決策は…​


残念ながら、それはIEでしか機能しないようです。 それで、この質問の本当の意味は、誰かがFFとChromeに有効な解決策を知っているかどうかということです。 さらに、フォーム要素自体に_onkeydown_イベントを追加する必要はありませんが、それが唯一の方法である場合は、追加する必要があります。

この問題は question 905222と似ていますが、私の意見ではそれ自体の問題に値するものです。

編集:また、私は人々がこれが良いスタイルではないという問題を提起しているのを見ました。 同意する! それはクライアントの要求です:(

18 Answer


78


私はAndrewが提案した非常に効果的な論理を使いました。 そしてこれは私のバージョンです:

$( 'body')。on( 'キーダウン'、 '入力、選択、テキストエリア'、関数(e){var self = $(this)、form = self.parents( 'form:eq(0)')、 if(e.keyCode == 13){focusable = form.find( '入力、a、選択、ボタン、テキストエリア')。filter( ':visible'); next = focusable.eq(focusable.index) (this)1); if(next.length){next.focus();} else {form.submit();} return false;}});


18


[Tab]キーのように動作するように[Enter]キーをマッピング

私はhttps://stackoverflow.com/users/714905/andre-van-zuydam [Andre Van Zuydam]の答えを書き換えました。 これはEnterとShift Enterの両方を捉えます。 タブを前方に入力し、Shift Enterタブを後方に入力します。

また、フォーカスされている現在のアイテムによって「+ self +」が初期化される方法を書き直しました。 フォームもそのように選択されています。 これがコードです:

// Map [Enter] key to work like the [Tab] key
// Daniel P. Clark 2014

// Catch the keydown for the entire document
$(document).keydown(function(e) {

  // Set self as the current item in focus
  var self = $(':focus'),
      // Set the form by the current item in focus
      form = self.parents('form:eq(0)'),
      focusable;

  // Array of Indexable/Tab-able items
  focusable = form.find('input,a,select,button,textarea,div[contenteditable=true]').filter(':visible');

  function enterKey(){
    if (e.which === 13 && !self.is('textarea,div[contenteditable=true]')) { // [Enter] key

      // If not a regular hyperlink/button/textarea
      if ($.inArray(self, focusable) && (!self.is('a,button'))){
        // Then prevent the default [Enter] key behaviour from submitting the form
        e.preventDefault();
      } // Otherwise follow the link/button as by design, or put new line in textarea

      // Focus on the next item (either previous or next depending on shift)
      focusable.eq(focusable.index(self) + (e.shiftKey ? -1 : 1)).focus();

      return false;
    }
  }
  // We need to capture the [Shift] key and check the [Enter] key either way.
  if (e.shiftKey) { enterKey() } else { enterKey() }
});

理由* + textarea + *

含まれているのは、私たちが「* do *」タブ付けしたいからです。 また、一度入ってしまえば、Enterのデフォルトの動作で新しい行が挿入されるのを止めたくはありません。

理由* + a + および + button + *

デフォルトのアクションである ""がまだ次の項目にフォーカスすることを許可するのは、それらが常に別のページをロードするわけではないからです。 アコーディオンやタブ付きコンテンツなどのトリガー/効果がある可能性があります。 そのため、デフォルトの動作を起動し、そのページがその特殊効果を発揮したとしても、それが原因で次の項目に移動したい場合があります。


13


これは私のために働きました

$(document).on( 'keydown'、 ':tabbable'、関数(e){

if(e.which == 13 || e.keyCode == 13){e.preventDefault(); var $ canfocus = $( ':tabbable:visible')var index = $ canfocus.index(document.activeElement)1; if(index> = $ canfocus.length)index = 0。 $ canfocus.eq(index).focus(); }

;));
https://fiddle.jshell.net/MAYUR68268/exuyv5y1/4/[JsFiddle]


11


良いスクリプトをありがとう。

要素間を戻るために上記の関数にshiftイベントを追加したところです。誰かがこれを必要とするかもしれないと思いました。

$( 'body')。on( 'キーダウン'、 '入力、選択、テキストエリア'、関数(e){var self = $(this)、form = self.parents( 'form:eq(0)')、焦点が合う、次に、前に。

if(e.shiftKey){if(e.keyCode == 13){focusable = form.find( 'input、a、select、button、textarea')。filter( ':visible'); prev = focusable.eq(focusable.index(this)-1);

if(prev.length){prev.focus(); } else {form.submit();}そうでなければ(e.keyCode == 13){focusable = form.find( 'input、a、select、button、textarea')。filter( ':visible'); next = focusable.eq(focusable.index(this)1); if(next.length){next.focus(); } else {form.submit();} falseを返します。 ;}});


6


ここに示したすべての実装には問題があります。 テキストエリアや送信ボタンで適切に動作しないものもありますし、ほとんどの場合、シフトを使用して逆方向に移動することを許可しないものもあります。最後まで。

[enter]キーを[tab]キーのように動作させながらもテキスト領域と送信ボタンで適切に機能させるには、次のコードを使用します。 さらに、このコードを使用すると、シフトキーを使用して前後に移動したり、タブを前後左右に折り返したりできます。

ソースコード:https://github.com/mikbe/SaneEnterKey

CoffeeScript

mbsd_sane_enter_key =  - > input_types = "入力、選択、ボタン、テキストエリア" $( "body")。 "keydown"、入力タイプ、(e) - > enter_key = 13 tab_key = 9

[tab_key、enter_key]内のe.keyCode = self($)

e.keyCode == enter_keyおよび( "" submit "、" textarea "]のself.prop( 'type'))がtrueを返す場合は、Enterキーを押すときに#Enterキーを押すだけのコントロールもあります。

form = self.parents( 'form:eq(0)')

tab_index = parseInt(self.attr( 'tabindex'))tab_index input_array = form.find( "[tabindex]")。filter( ':visible')。sort((a、b)が存在する場合は、タブインデックスで並べ替えます。 ) - > parseInt($(a).attr( 'tabindex')) -  parseInt($(b).attr( 'tabindex')))それ以外の場合input_array = form.find(input_types).filter( ':visible')

#shiftを使用している場合は方向を逆にします。move_direction = if e.shiftKey then -1でない場合1 new_index = input_array.index(this)move_direction

#new_index == input_array.lengthの場合new_index = 0の場合はコントロールを折り返し、new_index == -1の場合new_index = input_array.lengthの場合1

move_to = input_array.eq(new_index)move_to.focus()move_to.select()

偽

$(ウィンドウ).on 'ready page:load'、 - > mbsd_sane_enter_key()

JavaScript

var mbsd_sane_enter_key = function(){var input_types; input_types = "入力、選択、ボタン、テキストエリア";

return $( "body")。on( "キーダウン"、input_types、function(e){var enter_key、form、input_array、move_direction、move_to、new_index、self、tab_index、tab_key; enter_key = 13; tab_key = 9;

if(e.keyCode === tab_key || e.keyCode === enter_key){self = $(this);

//一部のコントロールは、if(e.keyCode === enter_key)を押すと設計どおりに反応する

form = self.parents( 'form:eq(0)');

//存在する場合はタブインデックスでソートしますtab_index = parseInt(self.attr( 'tabindex')); if(tab_index){input_array = form.find( "[tabindex]")。filter( ':visible')。sort(関数(a、b){return parseInt($(a).attr( 'tabindex'))) -  parseInt($(b).attr( 'tabindex'));}); } else {input_array = form.find(input_types).filter( ':visible'); }

// shift move_direction = e.shiftKeyを使用する場合は方向を逆にします -1:1 new_index = input_array.index(this)move_direction;

//(new_index === input_array.length){new_index = 0;そうでなければ(new_index === -1){new_index = input_array.length  -  1; }

move_to = input_array.eq(new_index); move_to.focus(); move_to.select(); falseを返します。 ;}}); ;

$(ウィンドウ).on( '準備完了ページ:読み込み'、function(){mbsd_sane_enter_key();}


5


私が思い付いた最も単純なバニラJSスニペット:

document.addEventListener( 'keydown'、function(event){if(event.keyCode === 13

IE 9以降のブラウザで動作します。


4


この動作を変更すると、実際にネイティブに実装されているデフォルトの動作よりもはるかに優れたユーザーエクスペリエンスが生まれます。 単一行の入力ではenterがフォームを送信する傾向があるのに対し、enterキーの動作はユーザーの観点からはすでに矛盾していると考えてください。フィールド。

私は最近こんな風にしました(jQueryを使っています):

$( 'input.enterastab、select.enterastab、textarea.enterastab')。live( 'keydown'、関数(e){if(e.keyCode == 13){var focusable = $( 'input、a、select、 button、textarea ')。filter(':visible '); focusable.eq(focusable.index(this)1).focus(); falseを返す;}});

これはそれほど効率的ではありませんが、十分に機能し信頼性があります - このように振る舞うべき入力要素に 'enterastab’クラスを追加するだけです。


4


私はOPソリューションをKnockoutバインディングに作り直し、それを共有することを考えました。 どうもありがとう :-)

http://jsfiddle.net/damiensawyer/AWNxq/[Here's]フィドル
ボルボサーブメルセデスアウディ

ko.bindingHandlers.nextFieldOnEnter = {init:function(element、valueAccessor、allBindingsAccessor){$(element).on( 'keydown'、 '入力、選択'、function(e){var self = $(this)、form = $(element)、focusable、next; if(e.keyCode == 13){focusable = form.find( 'input、a、select、button、textarea')。filter( ':visible'); var nextIndex = focusable .index(this)== focusable.length -1? 0:focusable.index(this)1; next = focusable.eq(nextIndex); next.focus(); falseを返します。 ;}}); ;}};

ko.applyBindings({});


2


これは、他の答えをインスピレーションとして使ってenterを次のフィールドに進めるためのangular.jsディレクティブです。 私は角度付きでパッケージされたjQliteのみを使用しているので、ここにいくつかの、おそらく奇妙に見えるコードがあります。 私はここの機能のほとんどがすべてのブラウザ> IE8で機能すると信じています。

angular.module('myapp', [])
.directive('pdkNextInputOnEnter', function() {
    var includeTags = ['INPUT', 'SELECT'];

    function link(scope, element, attrs) {
        element.on('keydown', function (e) {
            // Go to next form element on enter and only for included tags
            if (e.keyCode == 13 && includeTags.indexOf(e.target.tagName) != -1) {
                // Find all form elements that can receive focus
                var focusable = element[0].querySelectorAll('input,select,button,textarea');

                // Get the index of the currently focused element
                var currentIndex = Array.prototype.indexOf.call(focusable, e.target)

                // Find the next items in the list
                var nextIndex = currentIndex == focusable.length - 1 ? 0 : currentIndex + 1;

                // Focus the next element
                if(nextIndex >= 0 && nextIndex < focusable.length)
                    focusable[nextIndex].focus();

                return false;
            }
        });
    }

    return {
        restrict: 'A',
        link: link
    };
});

要素に `+ pdk-next-input-on-enter +`ディレクティブを追加するだけで、作業中のアプリで使用する方法を次に示します。 私はバーコードスキャナーを使ってフィールドにデータを入力しています。スキャナーのデフォルト機能はキーボードをエミュレートし、スキャンしたバーコードのデータをタイプした後にエンターキーを挿入することです。

このコードには副作用が1つあります(私のユースケースにとっては良いことです)。ボタンにフォーカスを合わせると、enter keyupイベントによってボタンのアクションがアクティブになります。 私のマークアップの最後のフォーム要素は、バーコードをスキャンしてすべてのフィールドを「タブ化」した後にアクティブにするボタンであるため、これは私のフローには非常に役立ちました。

          {{labelDocument.SerialNumber}}

              Component Serials


                      {{serial.name}}





          Print


1


私は次のフィールドに移動するためにテンキーを押したがっていたという同様の問題を抱えていました。 今、私はあなたを助けると思うライブラリをリリースしました。

_ PlusAsTab:テンキーのプラスキーをタブキーに相当するものとして使用するjQueryプラグイン。 _

代わりに/↵を入力したいので、オプションを設定できます。 https://api.jquery.com/event.which/ [jQuery event.which demo]でどのキーを使用するのかを確認してください。

JoelPurra.PlusAsTab.setOptions({
  // Use enter instead of plus
  // Number 13 found through demo at
  // https://api.jquery.com/event.which/
  key: 13
});

// Matches all inputs with name "a[]" (needs some character escaping)
$('input[name=a\\[\\]]').plusAsTab();

https://joelpurra.com/projects/plusastab/docs/example/enter-as-tab.html [Tabデモとして入力]で自分で試してみることができます]。