jquery як зловити клавішу введення та змінити подію на вкладку


74

Я хочу рішення jquery, я повинен бути поруч, що потрібно зробити?

$('html').bind('keypress', function(e)
{
     if(e.keyCode == 13)
     {
         return e.keyCode = 9; //set event key to tab
     }
});

Я можу повернути false, і це перешкоджає натисканню клавіші enter, я думав, що можу просто змінити keyCode на 9, щоб зробити його вкладкою, але, схоже, це не працює. Я повинен бути поруч, що відбувається?


А як щодо того, щоб запобігти подальшій обробці події вищими шарами і замість того, щоб намагатися змінити поточну подію, випускаючи нову?
Spidey

З міркувань безпеки модифікація keyCode є дуже поганою ідеєю, і я щасливий, що найновіші браузери (IE11 + також) не підтримують цього (але IE 10 і раніше підтримували це). У будь-якому випадку я протягом останніх двох днів шукав найкращого рішення для вашого запитання (воно також було моє), і тут я знайшов дуже цікаві підходи та експерименти з вирішенням. Все-таки я думаю про найкращий підхід.
Міклош Криван,

Відповіді:


77

Ось рішення:

$('input').on("keypress", function(e) {
            /* ENTER PRESSED*/
            if (e.keyCode == 13) {
                /* FOCUS ELEMENT */
                var inputs = $(this).parents("form").eq(0).find(":input");
                var idx = inputs.index(this);

                if (idx == inputs.length - 1) {
                    inputs[0].select()
                } else {
                    inputs[idx + 1].focus(); //  handles submit buttons
                    inputs[idx + 1].select();
                }
                return false;
            }
        });

6
Це рішення не здається мені настільки чудовим. З одного боку, він не звертає уваги на властивості "табіндексу". Крім того, це специфічно для форм та елементів введення, тоді як (з невідомих причин) оригінальний запитувач, мабуть, хоче, щоб ефект був глобальним на всій сторінці.
Пойнті

1
@Pointy: це не вічне рішення, я хотів би бачити інші можливості від вас чи когось іншого :)
Сарфраз

Це робить трюк, але я хотів би побачити, чи інші люди мають різні рішення.
оплата

@payling: звичайно, це краще рішення :)
Сарфраз

@Pointy Я знаю, що минуло занадто багато часу з моменту запитання, але ви можете перевірити мою відповідь;)
Камран Ахмед,

33

Це працює ідеально!

 $('input').keydown( function(e) {
        var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
        if(key == 13) {
            e.preventDefault();
            var inputs = $(this).closest('form').find(':input:visible');
            inputs.eq( inputs.index(this)+ 1 ).focus();
        }
    });

2
Це не працює для Select та текстового поля поза формою. Ви можете змінити його, щоб він працював як для вибору, так і для будь-якого поля за межами форми.
bjan

2
@bjan просто змінити селектор jquery
Леандро

Хороший, але не парфет. Краще використовувати подію on, оскільки вона створює менше обробників подій (продуктивність) і працює для оновлених ajax об'єктів dom $ ('input').
On

2
@AndzejMaciusovic, це абсолютно оманливе $('input').keydown(...скорочення $('input').on("keypress".... Вони обидва одне і те ж. У вас є доказ?
азерафаті

9

Чому б не щось таке просте?

$(document).on('keypress', 'input', function(e) {

  if(e.keyCode == 13 && e.target.type !== 'submit') {
    e.preventDefault();
    return $(e.target).blur().focus();
  }

});

Таким чином, ви не ініціюєте подання, якщо ви вже не зосереджені на введеному типі "подати", і це поставить вас там, де ви зупинилися. Це також змушує його працювати для входів, які динамічно додаються на сторінку.

Примітка: Розмиття () стоїть перед фокусом () для всіх, хто може мати слухачів подій "on blur". Не обов'язково, щоб процес працював.


@versedi Я не вважаю, що це точно. Не могли б ви пояснити, що ви маєте на увазі? Це повинно чудово працювати в усіх операційних системах та браузерах, де використовується jQuery
rpearce

Це базується на коді клавіатури клавіатури, який у вашому випадку вказаний лише як 13. Нам слід пам’ятати про клавішу numpad Enter, яка має окремий код - 3 у Mac (це не впливає на Windows, яка використовує 13 для обох).
versedi

То в чому проблема? Просто зроби це(e.keyCode == 13) || (e.keyCode == 3 )
Рісінек

Початкове питання полягало в тому, щоб змінити поведінку клавіші Enter на поведінку клавіші вкладки, а не просто вловити натиснуту клавішу Enter.
Міклош Криван,

7

PlusAsTab : плагін jQuery для використання клавіші numpad plus як еквівалента клавіші табуляції.

PlusAsTab також можна налаштувати на використання клавіші Enter, як у цій демонстрації . Дивіться деякі мої давніші відповіді на це питання .

У вашому випадку, заміна клавіші Enter функцією табуляції для всієї сторінки (після встановлення клавіші Enter як вкладки в опціях).

<body data-plus-as-tab="true">
    ...
</body>

Дуже добре, Джоеле! Працюючи з залежністю модуля github, спочатку мене спонукав цикл.

@RiverC: так, підмодулі можуть бути складними, якщо ви їх забудете, особливо з бібліотеками javascript. Оновлено документацію для включення підмодулів як рекомендації щодо клонування. git clone --recursive git://github.com/joelpurra/plusastab.git
Джоел Пурра,

Мені подобається плагін в Джоелі, але, схоже, при використанні зразка, представленого в демонстрації "Enter As Tab", він не розпізнає tabindex.
Ed DeGagne

@EdDeGagne: tabindexдизайн ігнорує - див. SkipOnTab проти tabindex . Мабуть, слід написати щось подібне або посилання на цю сторінку з PlusAsTab та EmulateTab.
Джоел Пурра,

5

Побудована з плагіна Бена, ця версія обробляє select, і ви можете передати опцію allowSubmit. тобто $("#form").enterAsTab({ 'allowSubmit': true}); Це дозволить Enter надіслати форму, якщо кнопка "Надіслати" обробляє подію.

(function( $ ){
    $.fn.enterAsTab = function( options ) {  
    var settings = $.extend( {
       'allowSubmit': false
    }, options);
    this.find('input, select').live("keypress", {localSettings: settings}, function(event) {
        if (settings.allowSubmit) {
        var type = $(this).attr("type");
        if (type == "submit") {
            return true;
        } 
    }
    if (event.keyCode == 13 ) {
        var inputs =   $(this).parents("form").eq(0).find(":input:visible:not(disabled):not([readonly])");
        var idx = inputs.index(this);
        if (idx == inputs.length - 1) {
           idx = -1;
       } else {
           inputs[idx + 1].focus(); // handles submit buttons
      }
        try {
            inputs[idx + 1].select();
            }
        catch(err) {
            // handle objects not offering select
            }
        return false;
    }
});
  return this;
};
})( jQuery );

поставити інвалідом у дужку в селекторі [відключено]
Міклош Криван

4

Я написав код із прийнятої відповіді як плагін jQuery, який мені здається більш корисним. (також, тепер він ігнорує приховані, відключені та лише форми читання елементи форми).

$.fn.enterAsTab = function () {
  $(this).find('input').live("keypress", function(e) {
    /* ENTER PRESSED*/
    if (e.keyCode == 13) {
        /* FOCUS ELEMENT */
        var inputs =   $(this).parents("form").eq(0).find(":input:visible:not(disabled):not([readonly])"),
            idx = inputs.index(this);

        if (idx == inputs.length - 1) {
            inputs[0].select()
        } else {
            inputs[idx + 1].focus(); // handles submit buttons
            inputs[idx + 1].select();
        }
        return false;
    }
  });
  return this;
};

Таким чином я можу зробити $ ('# form-id'). EnterAsTab (); ... Зрозумів, що я публікую повідомлення, оскільки ще ніхто не розміщував його як плагін $, і вони не зовсім інтуїтивно зрозумілі для написання.


Є щось подібне; випустити плагін пару місяців тому, див. мою відповідь.
Джоел Пурра,

4

Це нарешті те, що для мене працює ідеально. Я використовую jqeasyui, і він працює нормально

$(document).on('keyup', 'input', function(e) {
 if(e.keyCode == 13 && e.target.type        !== 'submit') {
   var inputs =   $(e.target).parents("form").eq(0).find(":input:visible"),
   idx = inputs.index(e.target);
       if (idx == inputs.length - 1) {
          inputs[0].select()
       } else {
          inputs[idx + 1].focus();
          inputs[idx + 1].select();
       }
 }

});

Дякуючи Метін, ти вирішив мою проблему, я додав перевірку біт-біт для select: $ (document) .on ('keyup', 'input, select', function (e) {
user3086295

4

Ось що я використовував:

$("[tabindex]").addClass("TabOnEnter");
$(document).on("keypress", ".TabOnEnter", function (e) {
 //Only do something when the user presses enter
     if (e.keyCode == 13) {
          var nextElement = $('[tabindex="' + (this.tabIndex + 1) + '"]');
          console.log(this, nextElement);
           if (nextElement.length)
                nextElement.focus()
           else
                $('[tabindex="1"]').focus();
      }
});

Звертає увагу на табіндекс і стосується не форми, а цілої сторінки.

Примітка live застаріла jQuery, тепер ви повинні використовуватиon


Це моя улюблена відповідь. У моєму випадку це добре працює, але слід зазначити, що не буде, якщо табіндекси елементів не будуть послідовними.
Джош Більдербек

Це добре, лише якщо у вас є табіндекс на елементах, інакше він не працює.
Міклош Криван,

3

Включає всі типи входів

$(':input').keydown(function (e) {
    var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
    if (key == 13) {
        e.preventDefault();
        var inputs = $(this).closest('form').find(':input:visible:enabled');
        if ((inputs.length-1) == inputs.index(this))
            $(':input:enabled:visible:first').focus();
        else
            inputs.eq(inputs.index(this) + 1).focus();
    }
});

Це не працює для мене. Я встановлюю все як enabled="false", встановлюю порядок tabindex, і натискання клавіші Enter, поки курсор знаходиться в текстовому полі, все одно запускає дію за замовчуванням (надішліть першу кнопку). Чи щось змінилося, що зробило б для мене цю потребу іншою? Я поняття не маю, що я роблю в Jquery, просто asp.NET та VB.NET.
pixelmeow 03.03.15

подивіться, чи є елемент керування в тезі "form" >> $ (this) .closest ('form'). length
pmereles

1
Цей мені сподобався найбільше! Я щойно додав невеличкі вдосконалення: 1) .find(':input:visible:enabled[tabindex!="-1"]').not(':input[readonly]');- пропустити лише читання та tabindex = -1 поля ... 2) if (key == 13 && $(this).attr('type') != 'submit')виключити кнопку подати
Рустам Гулієв

2

Це моє рішення, відгуки вітаються .. :)

$('input').keydown( function (event) { //event==Keyevent
    if(event.which == 13) {
        var inputs = $(this).closest('form').find(':input:visible');
        inputs.eq( inputs.index(this)+ 1 ).focus();
        event.preventDefault(); //Disable standard Enterkey action
    }
    // event.preventDefault(); <- Disable all keys  action
});

Але все-таки отримано негарне "Попередження: властивість 'charCode' події зниження клавіш не слід використовувати. ....". Якщо хтось знає, як від цього позбутися ...;) Гріц
Нік Ма.

2

Я взяв найкраще з вищезазначеного та додав можливість працювати з будь-якими введеннями, поза формами тощо. Крім того, він правильно циклічно повертається назад, щоб почати зараз, якщо ви досягли останнього вводу. А у випадку лише одного входу воно розмивається, після чого перефокусує одиночний вхід, щоб викликати будь-які зовнішні обробники розмиття / фокусування.

$('input,select').keydown( function(e) {
  var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
  if(key == 13) {
    e.preventDefault();
    var inputs = $('#content').find(':input:visible');
    var nextinput = 0;
    if (inputs.index(this) < (inputs.length-1)) {
      nextinput = inputs.index(this)+1;
    }
    if (inputs.length==1) {
      $(this).blur().focus();
    } else {
      inputs.eq(nextinput).focus();
    }
  }
});

Це чудово працює, за винятком текстових областей, де просто додається новий рядок (що може бути навмисним). Я не тестував радіо / прапорець / вибір. Однак я б не хотів підтримувати ваш код: читабельність - вимога :). Правильний інтервал і кріплення дуже важкий.
modle13

1

Ці рішення не працювали з моєю мережею даних. Я сподівався, що вони це зроблять. Мені насправді не потрібні Tab або Enter, щоб перейти до наступного вводу, стовпця, рядка чи чогось іншого. Мені просто потрібно Enter, щоб запустити .focusout або .change, і моя мережа даних оновлює базу даних. Тож я додав клас "enter" до відповідних введень тексту, і це зробило для мене фокус:

$(function() {
   if ($.browser.mozilla) {
        $(".enter").keypress(checkForEnter);
    } else {
        $(".enter").keydown(checkForEnter);
    }
});

function checkForEnter(event) {
    if (event.keyCode == 13) {
        $(".enter").blur();
    }
}

0
$('input').live("keypress", function(e) {
            /* ENTER PRESSED*/
            if (e.keyCode == 13) {
                /* FOCUS ELEMENT */
                var inputs = $(this).parents("form").eq(0).find(":input:visible");
                var idx = inputs.index(this);

                if (idx == inputs.length - 1) {
                    inputs[0].select()
                } else {
                    inputs[idx + 1].focus(); //  handles submit buttons
                    inputs[idx + 1].select();
                }
                return false;
            }
        });

видиме введення не можна сфокусувати.


0

Я знаю, що це питання старше бога, але я ніколи не бачив відповіді, яка була б настільки елегантною.

doc.on('keydown', 'input', function(e, ui) {
    if(e.keyCode === 13){
        e.preventDefault();
        $(this).nextAll('input:visible').eq(0).focus();
    }
});

здається, це робить роботу якомога менше рядків.


Насправді виглядає просто, але не дбайте про textarea та інвалідів, якщо я маю рацію. І, можливо, ви хочете залишитися в нинішній формі, як у пропозиції Сарфраза.
Міклош Криван,

0

ви повинні відфільтрувати всі відключені та лише для читання елементи. я думаю, що цей код не повинен охоплювати кнопки

$('body').on('keydown', 'input, select, textarea', function(e) {
    var self = $(this),
        form = self.parents('form:eq(0)'),
        submit = (self.attr('type') == 'submit' || self.attr('type') == 'button'),
        focusable,
        next;

    if (e.keyCode == 13 && !submit) {
        focusable = form.find('input,a,select,button,textarea').filter(':visible:not([readonly]):not([disabled])');
        next = focusable.eq(focusable.index(this)+1);

        if (next.length) {
            next.focus();
        } else {
            form.submit();
        }

        return false;
    }
});

0

У мене були такі самі вимоги при розробці, тому я досліджував це. За останні два дні я прочитав багато статей і спробував багато рішень, таких як плагін jQuery.tabNext ().

У мене були проблеми з IE11 (ця версія IE має цю помилку). Коли введений текст, за яким не вводиться текст, виділення не було очищено. Тож я створив власний метод tabNext () на основі пропозиції рішення @Sarfraz. Я також думав про те, як це повинно поводитись (лише коло в поточній формі або, можливо, через повний документ). Я все ще не піклувався про властивість табіндексу, здебільшого тому, що використовую його час від часу. Але я цього не забуду.

Щоб мій внесок міг бути корисним для всіх, я створив приклад jsfiddle тут https://jsfiddle.net/mkrivan/hohx4nes/

Тут я також включаю частину прикладу JavaScript:

            function clearSelection() {
            if (document.getSelection) { // for all new browsers (IE9+, Chrome, Firefox)
                document.getSelection().removeAllRanges();
                document.getSelection().addRange(document.createRange());
                console.log("document.getSelection");
            } else if (window.getSelection) { // equals with the document.getSelection (MSDN info)
                if (window.getSelection().removeAllRanges) {  // for all new browsers (IE9+, Chrome, Firefox)
                    window.getSelection().removeAllRanges();
                    window.getSelection().addRange(document.createRange());
                    console.log("window.getSelection.removeAllRanges");
                } else if (window.getSelection().empty) {  // maybe for old Chrome
                    window.getSelection().empty();
                    console.log("window.getSelection.empty");
                }
            } else if (document.selection) {  // IE8- deprecated
                document.selection.empty();
                console.log("document.selection.empty");
            }
        }
        function focusNextInputElement(node) { // instead of jQuery.tabNext();
            // TODO: take the tabindex into account if defined
            if (node !== null) {
                // stay in the current form
                var inputs = $(node).parents("form").eq(0).find(":input:visible:not([disabled]):not([readonly])");
                // if you want through the full document (as TAB key is working)
                // var inputs = $(document).find(":input:visible:not([disabled]):not([readonly])");
                var idx = inputs.index(node) + 1; // next input element index
                if (idx === inputs.length) { // at the end start with the first one
                    idx = 0;
                }
                var nextInputElement = inputs[idx];
                nextInputElement.focus(); //  handles submit buttons
                try { // if next input element does not support select()
                    nextInputElement.select();
                } catch (e) {
                }
            }
        }
        function tabNext() {
            var currentActiveNode = document.activeElement;
            clearSelection();
            focusNextInputElement(currentActiveNode);
        }
        function stopReturnKey(e) {
            var e = (e) ? e : ((event) ? event : null);
            if (e !== null) {
                var node = (e.target) ? e.target : ((e.srcElement) ? e.srcElement : null);
                if (node !== null) {
                    var requiredNode = $(node).is(':input')
                            // && !$(node).is(':input[button]')
                            // && !$(node).is(':input[type="submit"]')
                            && !$(node).is('textarea');
                    // console.log('event key code ' + e.keyCode + '; required node ' + requiredNode);
                    if ((e.keyCode === 13) && requiredNode) {
                        try {
                            tabNext();
                            // clearSelection();
                            // focusNextInputElement(node);
                            // jQuery.tabNext();
                            console.log("success");
                        } catch (e) {
                            console.log("error");
                        }
                        return false;
                    }
                }
            }
        }
        document.onkeydown = stopReturnKey;

Я також залишив коментовані рядки, щоб моє мислення можна було простежити.


Мені потрібно подякувати всім учасникам цієї теми. Без вас я не зміг би створити найкращий результат для своєї проблеми розвитку. Моє рішення - це інтеграція всіх ваших з багатьма тестуваннями та деякими доповненнями, звичайно.
Міклош Криван

0

Я знаю, що це досить давно, але я шукав ту саму відповідь і виявив, що обране рішення не підпорядковується tabIndex. Отже, я змінив його до наступного, що працює для мене. Зверніть увагу, що maxTabNumber - це глобальна змінна, яка містить максимальну кількість полів вводу, що можна вкласти

  $('input').on("keypress", function (e) {
                if (e.keyCode == 13) {
                    var inputs = $(this).parents("form").eq(0).find(":input");
                    var idx = inputs.index(this);

                    var tabIndex = parseInt($(this).attr("tabindex"));
                    tabIndex = (tabIndex + 1) % (maxTabNumber + 1);
                    if (tabIndex == 0) { tabIndex = 1; }
                    $('[tabindex=' + tabIndex + ']').focus();
                    $('[tabindex=' + tabIndex + ']').select();
          
                    return false;
                }
    });


0

Ось плагін jQuery, який я написав, який обробляє клавішу enter як зворотний дзвінок або як клавішу табуляції (з додатковим зворотним викликом):

$(document).ready(function() {
  $('#one').onEnter('tab');
  $('#two').onEnter('tab');
  $('#three').onEnter('tab');
  $('#four').onEnter('tab');
  $('#five').onEnter('tab');
});

/**
 * jQuery.onEnter.js
 * Written by: Jay Simons
 * Cloudulus.Media (https://code.cloudulus.media)
 */

if (window.jQuery) {
    (function ($) {
        $.fn.onEnter = function (opt1, opt2, opt3) {
            return this.on('keyup', function (e) {
                var me = $(this);
                var code = e.keyCode ? e.keyCode : e.which;
                if (code == 13) {
                    if (typeof opt1 == 'function')
                    {
                        opt1(me, opt2);
                        return true;
                    }else if (opt1 == 'tab')
                    {
                        var eles = $(document).find('input,select,textarea,button').filter(':visible:not(:disabled):not([readonly])');
                        var foundMe = false;
                        var next = null;
                        eles.each(function(){
                            if (!next){
                                if (foundMe) next = $(this);
                                if (JSON.stringify($(this)) == JSON.stringify(me)) foundMe = true;
                            }
                        });
                        next.focus();
                        if (typeof opt2 === 'function')
                        {
                            opt2(me, opt3);
                        }
                        return true;
                    }
                }
            }).on('keydown', function(e){
                var code = e.keyCode ? e.keyCode : e.which;
                if (code == 13)
                {
                    e.preventDefault();
                    e.stopPropagation();
                    return false;
                }
            });
        }
    })(jQuery);
} else {
    console.log("onEnter.js: This class requies jQuery > v3!");
}
input,
select,
textarea,
button {
  display: block;
  margin-bottom: 1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  <input id="one" type="text" placeholder="Input 1" />
  <input id="two" type="text" placeholder="Input 2" />

  <select id="four">
    <option selected>A Select Box</option>
    <option>Opt 1</option>
    <option>Opt 2</option>
  </select>
  <textarea id="five" placeholder="A textarea"></textarea>
  <input id="three" type="text" placeholder="Input 3" />
  <button>A Button</button>
</form>


0

Мені потрібно перейти далі лише до введення та вибору, а елемент повинен бути фокусованим. Цей сценарій для мене працює краще:

$('body').on('keydown', 'input, select', function(e) {
    if (e.key === "Enter") {
        var self = $(this), form = self.parents('form:eq(0)'), focusable, next;
        focusable = form.find('input,select,textarea').filter(':visible');
        next = focusable.eq(focusable.index(this)+1);
        if (next.length) {
            next.focus();
        } else {
            form.submit();
        }
        return false;
    }
});

Можливо, це комусь допомагає.


-1

Якщо ви використовуєте IE, це мені вдало:

    <body onkeydown="tabOnEnter()">
    <script type="text/javascript">
    //prevents the enter key from submitting the form, instead it tabs to the next field
    function tabOnEnter() {
        if (event.keyCode==13) 
        {
            event.keyCode=9; return event.keyCode 
        }
    }
    </script>

Вибачте, щойно побачив частину "jquery"
розчарування в

Це виглядає дуже просто, але, на жаль, не працює на IE11. Остання версія, де вона працює, - IE10 (я пробував з усіма режимами емуляції IE)
Міклош Криван,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.