按下回车键时如何将焦点移到下一个字段?
Posted
技术标签:
【中文标题】按下回车键时如何将焦点移到下一个字段?【英文标题】:How to move focus on next field when enter is pressed? 【发布时间】:2014-08-04 06:21:47 【问题描述】:你能告诉我按下回车键时如何将焦点移到下一个字段吗?我使用 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>
*注意(来自 cmets):它还需要在没有设置 tabindex
值的页面上工作
【问题讨论】:
我已经在所有 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();
);
如果您愿意,您可以在事件处理程序中使用相同的自定义选择器。然后它甚至可以在锚链接上工作(如果你将事件更改为 keydown 而不是 keypress):
例如
$(document).on('keydown', ':focusable', function (e)
链接示例:http://jsfiddle.net/5WkVW/15/
这也使用了一个委托on
,监听document
上的keydown
事件。它然后 应用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();
);
【讨论】:
完成...适用于两者..应该适用于任何东西! :) @Gone Coding:我不小心击中了箭头并给你投了反对票,但我刚刚注意到并且现在无法更改。对于那个很抱歉。显然,如果帖子被编辑,我可以删除它,所以如果你想做一个琐碎的编辑,我会这样做。 @Gone Coding:谢谢,我已经改了。 @GoneCoding 当下一个元素是禁用的输入元素时,此代码不起作用。有什么办法可以在 ":focusable" 列表中只添加 'not-disabled' 元素?? 我得到了答案。我刚刚将 ':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>
【讨论】:
避免使用大于 0 的 tabindex 值。这样做会使依赖辅助技术的人难以导航和操作页面内容。 From 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();
);
);
下拉菜单已经有用于打开下拉菜单的输入键。
JS FIDDLE DEMO
为了能够在移动到下一个表单元素之前做一些事情,您可以使用以下版本:
$(function()
$(document).on('keypress', function(e)
var that = document.activeElement;
if( e.which == 13 )
e.preventDefault();
alert( "dd" );
$('[tabIndex=' + (+that.tabIndex + 1) + ']')[0].focus();
);
);
DEMO
【讨论】:
我们可以在我的代码上更改您的代码吗?使用文档? like $(document).keypress(function(e) if(e.which == 13) // 如果弹出窗口打开,则在此处执行一些操作 alert("dd") var index = $('.ui-dform-text').index(this) + 1; $('.ui-dform-text').eq(index).focus(); ); 当然可以,让我看看我能把什么放在一起。 这很好(在发现 tabindex 存在时做得很好),但它不会环绕或允许在选择时输入。 @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();
);
【讨论】:
不幸的是(如果您关注 cmets),它还需要在没有tabindex
属性的页面上工作:(【参考方案6】:
看起来一样,但我提供了一些简单、可能有用且易于记忆的东西,这就是我使用的东西
html
<input placeholder="nama">
<input placeholder="email">
<input placeholder="password">
<button>MASUK<button>
js
$('INPUT').keydown( e => e.which === 13?$(e.target).next().focus():"");
【讨论】:
【参考方案7】:// 这会起作用;在您的就绪函数中添加此代码并定义您的父元素,其中包括要关注的子元素。
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" && (event.target.innerHTML !== "" && 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);
【讨论】:
【参考方案8】:1.first = 你应该在你的类名上输入'textbox'
2.second = 为每个输入输入特定的 id
然后编写此代码以选择该元素并转到下一个元素。
我通过每个 id 选择每个元素,并将 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 args 用于我们按下 eneter 的元素
【讨论】:
【参考方案9】:这主要是个玩笑,但这里是一个使用最新 API 的 Vanilla JS 版本,只要你有一个现代浏览器,它应该是防弹的
这是发生了什么:
-
选择元素、输入等...(不包括禁用、隐藏等...)
使用展开语法,将数组(NodeList)转换为对象(这里是NodeObject)
循环遍历对象,也就是元素,也就是节点
每次迭代都会将当前元素 (Node) 和下一个元素 (NextNode) 传递给箭头函数。
如果 NextNode 是元素则继续
然后给当前元素添加按键事件
活动内部:
仅在按下回车键时继续(使用 e.key NOT 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 );
【讨论】:
以上是关于按下回车键时如何将焦点移到下一个字段?的主要内容,如果未能解决你的问题,请参考以下文章