Enter key press behaves like a Tab in Javascript

后端 未结 22 1146
说谎
说谎 2020-11-27 10:52

I\'m looking to create a form where pressing the enter key causes focus to go to the \"next\" form element on the page. The solution I keep finding on the web is...

相关标签:
22条回答
  • 2020-11-27 11:13

    Try this...

    $(document).ready(function () {
        $.fn.enterkeytab = function () {
            $(this).on('keydown', 'input,select,text,button', function (e) {
                var self = $(this)
                  , form = self.parents('form:eq(0)')
                  , focusable
                  , next
                ;
                if (e.keyCode == 13) {
                    focusable = form.find('input,a,select').filter(':visible');
                    next = focusable.eq(focusable.index(this) + 1);
                    if (next.length) {
                        //if disable try get next 10 fields
                        if (next.is(":disabled")){
                            for(i=2;i<10;i++){
                                next = focusable.eq(focusable.index(this) + i);
                                if (!next.is(":disabled"))
                                    break;
                            }
                        }
                        next.focus();
                    }
                    return false;
                }
            });
        }
        $("form").enterkeytab();
    });
    
    0 讨论(0)
  • 2020-11-27 11:14

    Map [Enter] key to work like the [Tab] key

    I've rewritten Andre Van Zuydam's answer, which didn't work for me, in jQuery. This caputures both Enter and Shift+Enter. Enter tabs forward, and Shift+Enter tabs back.

    I've also rewritten the way self is initialized by the current item in focus. The form is also selected that way. Here's the code:

    // 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() }
    });
    

    The reason textarea

    is included is because we "do" want to tab into it. Also, once in, we don't want to stop the default behavior of Enter from putting in a new line.

    The reason a and button

    allow the default action, "and" still focus on the next item, is because they don't always load another page. There can be a trigger/effect on those such as an accordion or tabbed content. So once you trigger the default behavior, and the page does its special effect, you still want to go to the next item since your trigger may have well introduced it.

    0 讨论(0)
  • 2020-11-27 11:15

    The simplest vanilla JS snippet I came up with:

    document.addEventListener('keydown', function (event) {
      if (event.keyCode === 13 && event.target.nodeName === 'INPUT') {
        var form = event.target.form;
        var index = Array.prototype.indexOf.call(form, event.target);
        form.elements[index + 1].focus();
        event.preventDefault();
      }
    });
    

    Works in IE 9+ and modern browsers.

    0 讨论(0)
  • 2020-11-27 11:15

    In all that cases, only works in Chrome and IE, I added the following code to solve that:

    var key = (window.event) ? e.keyCode : e.which;

    and I tested the key value on if keycode equals 13

        $('body').on('keydown', 'input, select, textarea', function (e) {
        var self = $(this)
          , form = self.parents('form:eq(0)')
          , focusable
          , next
        ;
    
        var key = (window.event) ? e.keyCode : e.which;
    
        if (key == 13) {
            focusable = form.find('input,a,select,button,textarea').filter(':visible');
            next = focusable.eq(focusable.index(this) + 1);
            if (next.length) {
                next.focus();
            } else {
                focusable.click();
            }
            return false;
        }
    });
    
    0 讨论(0)
  • 2020-11-27 11:19

    Many answers here uses e.keyCode and e.which that are deprecated.

    Instead you should use e.key === 'Enter'.

    Documentation: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

    • I'm sorry but I can't test these snippets just now. Will come back later after testing it.

    With HTML:

    <body onkeypress="if(event.key==='Enter' && event.target.form){focusNextElement(event); return false;}">
    

    With jQuery:

    $(window).on('keypress', function (ev)
    {
        if (ev.key === "Enter" && ev.currentTarget.form) focusNextElement(ev)
    }
    

    And with Vanilla JS:

    document.addEventListener('keypress', function (ev) {
        if (ev.key === "Enter" && ev.currentTarget.form) focusNextElement(ev);
    });
    

    You can take focusNextElement() function from here: https://stackoverflow.com/a/35173443/3356679

    0 讨论(0)
  • 2020-11-27 11:20

    You could programatically iterate the form elements adding the onkeydown handler as you go. This way you can reuse the code.

    0 讨论(0)
提交回复
热议问题