[英]Enter key press behaves like a Tab in Javascript
我正在寻找创建一个表单,在该表单中按下回车键会使焦点转到 go 到页面上的“下一个”表单元素。 我一直在 web 上找到的解决方案是......
<body onkeydown="if(event.keyCode==13){event.keyCode=9; return event.keyCode}">
不幸的是,这似乎只适用于 IE。 所以这个问题的实质是,是否有人知道适用于 FF 和 Chrome 的解决方案? 此外,我宁愿不必将onkeydown事件添加到表单元素本身,但如果这是唯一的方法,那么它就必须这样做。
这个问题与问题 905222类似,但在我看来值得单独提问。
编辑:另外,我看到人们提出这样的问题,即这不是好的风格,因为它与用户习惯的表单行为不同。 我同意:这是客户要求:(
我使用了安德鲁建议的逻辑,这非常有效。 这是我的版本:
$('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,a,select,button,textarea').filter(':visible');
next = focusable.eq(focusable.index(this)+1);
if (next.length) {
next.focus();
} else {
form.submit();
}
return false;
}
});
KeyboardEvent 的键码(即: e.keycode
)折旧通知:- https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
我想出的最简单的 vanilla JS 片段:
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();
}
});
适用于 IE 9+ 和现代浏览器。
我在 jQuery 中重写了 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
的原因被包括在内是因为我们“确实”想要进入它。 此外,一旦进入,我们不想阻止Enter的默认行为放入新行。
a
和button
允许默认操作,“和”仍然关注下一个项目,因为它们并不总是加载另一个页面。 可以对手风琴或选项卡式内容等内容产生触发/效果。 因此,一旦您触发了默认行为,并且页面产生了特殊效果,您仍然希望 go 到下一个项目,因为您的触发器可能已经很好地引入了它。
谢谢你的好剧本。
我刚刚在上面的 function 到 go 元素之间添加了 shift 事件,我想有人可能需要这个。
$('body').on('keydown', 'input, select, textarea', function(e) {
var self = $(this)
, form = self.parents('form:eq(0)')
, focusable
, next
, prev
;
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();
}
}
}
else
if (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();
}
return false;
}
});
这对我有用:
$(document).on('keydown', ':tabbable', function(e) {
if (e.key === "Enter") {
e.preventDefault();
var $canfocus = $(':tabbable:visible');
var index = $canfocus.index(document.activeElement) + 1;
if (index >= $canfocus.length) index = 0;
$canfocus.eq(index).focus();
}
});
这里给出的所有实现都存在问题。 有些不能正常使用文本区域和提交按钮,大多数不允许您向后使用 shift to go,如果您有它们,它们都不使用 tabindexes,并且它们都不会从最后一个到第一个或第一个环绕到最后。
要使 [enter] 键像 [tab] 键一样工作,但仍能正确处理文本区域和提交按钮,请使用以下代码。 此外,此代码允许您向后使用 go 的 shift 键,并且制表符从前到后和从后到前环绕。
源码: https://github.com/mikbe/SaneEnterKey
mbsd_sane_enter_key = ->
input_types = "input, select, button, textarea"
$("body").on "keydown", input_types, (e) ->
enter_key = 13
tab_key = 9
if e.keyCode in [tab_key, enter_key]
self = $(this)
# some controls should just press enter when pressing enter
if e.keyCode == enter_key and (self.prop('type') in ["submit", "textarea"])
return true
form = self.parents('form:eq(0)')
# Sort by tab indexes if they exist
tab_index = parseInt(self.attr('tabindex'))
if tab_index
input_array = form.find("[tabindex]").filter(':visible').sort((a,b) ->
parseInt($(a).attr('tabindex')) - parseInt($(b).attr('tabindex'))
)
else
input_array = form.find(input_types).filter(':visible')
# reverse the direction if using shift
move_direction = if e.shiftKey then -1 else 1
new_index = input_array.index(this) + move_direction
# wrap around the controls
if new_index == input_array.length
new_index = 0
else if new_index == -1
new_index = input_array.length - 1
move_to = input_array.eq(new_index)
move_to.focus()
move_to.select()
false
$(window).on 'ready page:load', ->
mbsd_sane_enter_key()
var mbsd_sane_enter_key = function() {
var input_types;
input_types = "input, select, button, textarea";
return $("body").on("keydown", 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);
// some controls should react as designed when pressing enter
if (e.keyCode === enter_key && (self.prop('type') === "submit" || self.prop('type') === "textarea")) {
return true;
}
form = self.parents('form:eq(0)');
// Sort by tab indexes if they exist
tab_index = parseInt(self.attr('tabindex'));
if (tab_index) {
input_array = form.find("[tabindex]").filter(':visible').sort(function(a, b) {
return parseInt($(a).attr('tabindex')) - parseInt($(b).attr('tabindex'));
});
} else {
input_array = form.find(input_types).filter(':visible');
}
// reverse the direction if using shift
move_direction = e.shiftKey ? -1 : 1;
new_index = input_array.index(this) + move_direction;
// wrap around the controls
if (new_index === input_array.length) {
new_index = 0;
} else if (new_index === -1) {
new_index = input_array.length - 1;
}
move_to = input_array.eq(new_index);
move_to.focus();
move_to.select();
return false;
}
});
};
$(window).on('ready page:load', function() {
mbsd_sane_enter_key();
}
我将 OPs 解决方案重新设计为 Knockout 绑定,并认为我会分享它。 非常感谢:-)
这是一个小提琴
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js" type="text/javascript"></script>
</head>
<body>
<div data-bind="nextFieldOnEnter:true">
<input type="text" />
<input type="text" />
<select>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<input type="text" />
<input type="text" />
</div>
<script type="text/javascript">
ko.bindingHandlers.nextFieldOnEnter = {
init: function(element, valueAccessor, allBindingsAccessor) {
$(element).on('keydown', 'input, select', 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();
return false;
}
});
}
};
ko.applyBindings({});
</script>
</body>
</html>
改变这种行为实际上创造了比本机实现的默认行为更好的用户体验。 考虑到 enter 键的行为从用户的角度来看已经不一致了,因为在单行输入中,enter 倾向于提交一个表单,而在多行 textarea 中,它只是简单地在内容中添加一个换行符场地。
我最近是这样做的(使用 jQuery):
$('input.enterastab, select.enterastab, textarea.enterastab').live('keydown', function(e) {
if (e.keyCode==13) {
var focusable = $('input,a,select,button,textarea').filter(':visible');
focusable.eq(focusable.index(this)+1).focus();
return false;
}
});
这不是非常有效,但工作得很好并且可靠 - 只需将 'enterastab' class 添加到任何应该以这种方式运行的输入元素。
这是一个 angular.js 指令,使用其他答案作为灵感,使输入 go 到下一个字段。 这里可能有一些看起来很奇怪的代码,因为我只使用与 angular 一起打包的 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
指令。 我正在使用条形码扫描仪将数据输入字段,扫描仪的默认 function 是模拟键盘,在输入扫描条形码的数据后注入回车键。
这段代码有一个副作用(对我的用例来说是一个积极的副作用),如果它把焦点移到一个按钮上,enter keyup 事件将导致按钮的动作被激活。 这对我的流程非常有效,因为我标记中的最后一个表单元素是一个按钮,我希望在通过扫描条形码“标记”所有字段后激活该按钮。
<!DOCTYPE html>
<html ng-app=myapp>
<head>
<script src="angular.min.js"></script>
<script src="controller.js"></script>
</head>
<body ng-controller="LabelPrintingController">
<div class='.container' pdk-next-input-on-enter>
<select ng-options="p for p in partNumbers" ng-model="selectedPart" ng-change="selectedPartChanged()"></select>
<h2>{{labelDocument.SerialNumber}}</h2>
<div ng-show="labelDocument.ComponentSerials">
<b>Component Serials</b>
<ul>
<li ng-repeat="serial in labelDocument.ComponentSerials">
{{serial.name}}<br/>
<input type="text" ng-model="serial.value" />
</li>
</ul>
</div>
<button ng-click="printLabel()">Print</button>
</div>
</body>
</html>
试试这个...
$(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();
});
function return2tab (div)
{
document.addEventListener('keydown', function (ev) {
if (ev.key === "Enter" && ev.target.nodeName === 'INPUT') {
var focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"], [contenteditable]';
let ol= div.querySelectorAll(focusableElementsString);
for (let i=0; i<ol.length; i++) {
if (ol[i] === ev.target) {
let o= i<ol.length-1? ol[i+1]: o[0];
o.focus(); break;
}
}
ev.preventDefault();
}
});
}
我遇到了类似的问题,我想在小键盘上按+以切换到下一个字段。 现在,我发布了一个我认为会对您有所帮助的库。
PlusAsTab :一个 jQuery 插件,用于将小键盘加号键用作等效的制表键。
由于您想要输入/ ↵ ,您可以设置选项。 通过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();
您可以在PlusAsTab enter as tab demo中自己尝试一下。
如果可以的话,我会重新考虑这样做:在表单中按<Enter>
的默认操作会提交表单,而您为更改此默认操作/预期行为所做的任何操作都可能导致网站出现一些可用性问题。
我让它只在 JavaScript 中工作。Firefox 不会让你更新 keyCode,所以你所能做的就是捕获 keyCode 13 并强制它通过 tabIndex 关注下一个元素,就像按下 keyCode 9 一样。 棘手的部分是找到下一个 tabIndex。 我只在 IE8-IE10 和 Firefox 上测试过它并且它有效:
function ModifyEnterKeyPressAsTab(event)
{
var caller;
var key;
if (window.event)
{
caller = window.event.srcElement; //Get the event caller in IE.
key = window.event.keyCode; //Get the keycode in IE.
}
else
{
caller = event.target; //Get the event caller in Firefox.
key = event.which; //Get the keycode in Firefox.
}
if (key == 13) //Enter key was pressed.
{
cTab = caller.tabIndex; //caller tabIndex.
maxTab = 0; //highest tabIndex (start at 0 to change)
minTab = cTab; //lowest tabIndex (this may change, but start at caller)
allById = document.getElementsByTagName("input"); //Get input elements.
allByIndex = []; //Storage for elements by index.
c = 0; //index of the caller in allByIndex (start at 0 to change)
i = 0; //generic indexer for allByIndex;
for (id in allById) //Loop through all the input elements by id.
{
allByIndex[i] = allById[id]; //Set allByIndex.
tab = allByIndex[i].tabIndex;
if (caller == allByIndex[i])
c = i; //Get the index of the caller.
if (tab > maxTab)
maxTab = tab; //Get the highest tabIndex on the page.
if (tab < minTab && tab >= 0)
minTab = tab; //Get the lowest positive tabIndex on the page.
i++;
}
//Loop through tab indexes from caller to highest.
for (tab = cTab; tab <= maxTab; tab++)
{
//Look for this tabIndex from the caller to the end of page.
for (i = c + 1; i < allByIndex.length; i++)
{
if (allByIndex[i].tabIndex == tab)
{
allByIndex[i].focus(); //Move to that element and stop.
return;
}
}
//Look for the next tabIndex from the start of page to the caller.
for (i = 0; i < c; i++)
{
if (allByIndex[i].tabIndex == tab + 1)
{
allByIndex[i].focus(); //Move to that element and stop.
return;
}
}
//Continue searching from the caller for the next tabIndex.
}
//The caller was the last element with the highest tabIndex,
//so find the first element with the lowest tabIndex.
for (i = 0; i < allByIndex.length; i++)
{
if (allByIndex[i].tabIndex == minTab)
{
allByIndex[i].focus(); //Move to that element and stop.
return;
}
}
}
}
要使用此代码,请将其添加到您的 html 输入标签中:
<input id="SomeID" onkeydown="ModifyEnterKeyPressAsTab(event);" ... >
或者将它添加到 javascript 中的一个元素中:
document.getElementById("SomeID").onKeyDown = ModifyEnterKeyPressAsTab;
其他一些注意事项:
我只需要它来处理我的输入元素,但如果需要,您可以将它扩展到其他文档元素。 为此,getElementsByClassName 非常有帮助,但那是另一个话题。
一个限制是它只在您添加到 allById 数组的元素之间制表。 它不会切换到浏览器可能出现的其他内容,例如 html 文档之外的工具栏和菜单。 也许这是一个功能而不是限制。 如果您愿意,可以捕获 keyCode 9,此行为也适用于 Tab 键。
您可以使用我在 Mozilla、IE 和 Chrome 中测试过的代码
// Use to act like tab using enter key
$.fn.enterkeytab=function(){
$(this).on('keydown', 'input, select,', function(e) {
var self = $(this)
, form = self.parents('form:eq(0)')
, focusable
, next
;
if (e.keyCode == 13) {
focusable = form.find('input,a,select,button').filter(':visible');
next = focusable.eq(focusable.index(this)+1);
if (next.length) {
next.focus();
} else {
alert("wd");
//form.submit();
}
return false;
}
});
}
如何使用?
$("#form").enterkeytab(); // 输入关键选项卡
Vanilla js 支持 Shift + Enter 并能够选择可聚焦的 HTML 标签。 应该工作 IE9 +。
onKeyUp(e) {
switch (e.keyCode) {
case 13: //Enter
var focusableElements = document.querySelectorAll('input, button')
var index = Array.prototype.indexOf.call(focusableElements, document.activeElement)
if(e.shiftKey)
focus(focusableElements, index - 1)
else
focus(focusableElements, index + 1)
e.preventDefault()
break;
}
function focus(elements, index) {
if(elements[index])
elements[index].focus()
}
}
这里的许多答案都使用已弃用的e.keyCode
和e.which
。
相反,您应该使用e.key === 'Enter'
。
文档: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
使用 HTML:
<body onkeypress="if(event.key==='Enter' && event.target.form){focusNextElement(event); return false;}">
使用 jQuery:
$(window).on('keypress', function (ev)
{
if (ev.key === "Enter" && ev.currentTarget.form) focusNextElement(ev)
}
和香草 JS:
document.addEventListener('keypress', function (ev) {
if (ev.key === "Enter" && ev.currentTarget.form) focusNextElement(ev);
});
您可以从这里获取focusNextElement()
function: https://stackoverflow.com/a/35173443/3356679
这是我想出的。
form.addEventListener("submit", (e) => { //On Submit
let key = e.charCode || e.keyCode || 0 //get the key code
if (key = 13) { //If enter key
e.preventDefault()
const inputs = Array.from(document.querySelectorAll("form input")) //Get array of inputs
let nextInput = inputs[inputs.indexOf(document.activeElement) + 1] //get index of input after the current input
nextInput.focus() //focus new input
}
}
解决这个问题最简单的方法是JavaScript的焦点function如下:
你可以复制试试@home!
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<input id="input1" type="text" onkeypress="pressEnter()" />
<input id="input2" type="text" onkeypress="pressEnter2()" />
<input id="input3" type="text"/>
<script type="text/javascript">
function pressEnter() {
// Key Code for ENTER = 13
if ((event.keyCode == 13)) {
document.getElementById("input2").focus({preventScroll:false});
}
}
function pressEnter2() {
if ((event.keyCode == 13)) {
document.getElementById("input3").focus({preventScroll:false});
}
}
</script>
</body>
</html>
我在React js中使用回车键而不是 Tab 时遇到问题。anjana-silva的解决方案工作正常,只是输入日期和自动完成的一些小问题,因为我正在使用 MUI。 所以我稍微改变了它并添加了箭头键(左/右)。
使用 npm 安装 jquery
npm install jquery --save
在App.js中写下如果你想在整个应用程序中有这种行为
import $ from 'jquery';
useEffect(() => {
$('body').on('keydown', 'input, select,button', function (e) {
if (e.keyCode === 13 || e.keyCode === 39) {
var self = $(this), form = self.parents('form:eq(0)'), focusable, next;
focusable = form.find('input,a,select,button,textarea').filter(':visible:not([readonly]):enabled');
next = focusable.eq(focusable.index(this) + 1);
if (next.length) {
next.focus();
}
return false;
}
if (e.keyCode === 37) {
var self = $(this), form = self.parents('form:eq(0)'), focusable, prev;
focusable = form.find('input,a,select,button,textarea').filter(':visible:not([readonly]):enabled');
prev = focusable.eq(focusable.index(this) - 1);
if (prev.length) {
prev.focus();
}
return false;
}
});
}, []);
我有一个类似的需要。 这是我所做的:
<script type="text/javascript" language="javascript">
function convertEnterToTab() {
if(event.keyCode==13) {
event.keyCode = 9;
}
}
document.onkeydown = convertEnterToTab;
</script>
在所有这些情况下,仅适用于 Chrome 和 IE,我添加了以下代码来解决该问题:
var key = (window.event)? e.keyCode: e.which;
如果键码等于 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;
}
});
$("#form input , select , textarea").keypress(function(e){
if(e.keyCode == 13){
var enter_position = $(this).index();
$("#form input , select , textarea").eq(enter_position+1).focus();
}
});
您可以在 go 中以编程方式迭代添加 onkeydown 处理程序的表单元素。这样您就可以重用代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.