如何使<input>
元素中的Enter键将焦点转移到页面上的下一个<input>
元素?
我有一个 for 循环,可以创建包含<input>
元素的<li>
元素。我需要这样做,以便当用户在键盘上按 Enter 时,网站将专注于下一个输入字段,以便用户可以输入下一个玩家名称,而无需在使用鼠标和键盘之间切换。
我认为使用nextSibling
属性是解决方案,但它不起作用,因为<input>
元素在技术上没有任何兄弟姐妹,因为它们中的每一个都在不同<li>
元素的内部/是子元素。
这是我的JavaScript:
for ( var i = 1 ; i <= numberOfPlayers ; i++ ){
var inputElement = document.createElement('input');
var liElement = document.createElement('li');
inputElement.setAttribute( 'type' , 'text' );
inputElement.setAttribute ( 'id' , 'name-input-' + i );
inputElement.setAttribute ( 'class' , 'name-input');
inputElement.setAttribute ( 'placeholder' , 'Enter a name for player ' + i );
liElement.appendChild(inputElement);
nameInputArray[i] = inputElement;
document.getElementById('name-list').appendChild(liElement);
inputElement.addEventListener( 'keypress' , function(event){
if ( event.which === 13 ) {
alert(this);
document.getElementById( 'name-input-' + (i+1)).focus();
}
} );
}
我尝试在 for 循环和字符串连接中使用"i"来选择下一个元素的 ID,但"i"变量也不起作用,因为当代码运行时,"i"等于整个 for 循环运行后它可以达到的最高数字。
问题:
实际代码的问题在于,i
总是等于事件处理程序callback
函数中的numberOfPlayers+1
,因此您尝试专注于null
元素,您可以阅读有关JavaScript闭包的更多信息,以了解为什么i
总是等于numberOfPlayers+1
。
溶液:
首先,您需要在输入上使用onkeypress
事件,然后测试按下的键是否为Enter,如果按下,则获取当前input
的id
,从中提取i
值并使用下一个id
专注于下一个input
元素。
这是你的代码应该如何:
inputElement.addEventListener('keypress', function(event) {
if (event.which === 13) {
var i = parseInt(this.id.charAt(this.id.length-1));
console.log(i);
if(i<=numberOfPlayers){
document.getElementById('name-input-' + (i + 1)).focus();
}
}
});
这是一个工作片段:
var numberOfPlayers = 5;
var nameInputArray = [];
for (var i = 1; i <= numberOfPlayers; i++) {
var inputElement = document.createElement('input');
var liElement = document.createElement('li');
inputElement.setAttribute('type', 'text');
inputElement.setAttribute('id', 'name-input-' + i);
inputElement.setAttribute('class', 'name-input');
inputElement.setAttribute('placeholder', 'Enter a name for player ' + i);
liElement.appendChild(inputElement);
nameInputArray[i] = inputElement;
document.getElementById('name-list').appendChild(liElement);
inputElement.addEventListener('keypress', function(event) {
if (event.which === 13) {
var i = parseInt(this.id.charAt(this.id.length - 1));
console.log(i);
if(i<numberOfPlayers){
document.getElementById('name-input-' + (i + 1)).focus();
}
}
});
}
<ul id="name-list"></ul>
如果你想坚持使用vanilla JS,请使用这个:
for (var i = 1; i <= numberOfPlayers; i++) {
var inputElement = document.createElement("input");
var liElement = document.createElement("li");
inputElement.type = "text";
inputElement.id = "name-input-" + i;
inputElement.className = "name-input";
inputElement.placeholder = "Enter a name for player " + i;
liElement.appendChild(inputElement);
nameInputArray[i] = inputElement;
document.getElementById("name-list").appendChild(liElement);
(function(i) {
inputElement.addEventListener("keypress", function(event) {
if (event.which === 13) {
alert(this);
document.getElementById("name-input-" + (i + 1)).focus();
}
});
})(i);
}
这是我的解决方案。
不要忘记创建的<li>
元素需要附加到类似<body>
.我实际上添加了一个<ul>
元素并将其附加到<body>
,然后将<li>
元素附加到<ul>
元素。
如果使用nextSibling
,则不需要将元素保留在nameInputArray
中。我没有删除它来显示在循环中使用它之前应该如何初始化它。此外,nextSibling
在我的解决方案中起作用,因为我已将所有<li>
放在一个<ul>
下,我认为无论如何都是正确的做法。
除此之外,我只是在这里和那里纠正了一些事情。如果您对这段代码有更多疑问,请告诉我。
function eventFunc(event) {
if (event.which === 13) {
var nextInput = event.target.parentElement.nextSibling.childNodes[0];
if (nextInput !== null)
nextInput.focus();
}
}
var numberOfPlayers = 4;
var nameInputArray = [];
var ulElement = document.createElement('ul');
document.body.append(ulElement);
for (var i = 0; i < numberOfPlayers; i++) {
var liElement = document.createElement('li');
ulElement.append(liElement);
var inputElement = document.createElement('input');
inputElement.setAttribute('type', 'text');
inputElement.setAttribute('id', 'name-input-' + i);
inputElement.setAttribute('class', 'name-input');
inputElement.setAttribute('placeholder', 'Enter a name for player ' + i);
inputElement.setAttribute('onkeypress', "eventFunc(event)");
liElement.appendChild(inputElement);
nameInputArray[i] = inputElement;
}
更新:从父元素获取每个输入框<li>
:
在OP发表评论后,我看到他们想要这样的结构:
<ul>
<li>input box1</li>
<li>input box2</li>
<li>input box3</li>
</ul>
在此结构中,每个输入框都是其父<li>
元素的第一个子节点。因此,我们仍然可以通过以下方式使用nextSibling
(如 OP 打算使用):
nextInput = event.target.parentElement.nextSibling.childNodes[0];
此行首先查找父元素<li>
,应用nextSibling
以获取下一个li
元素,然后获取该元素内的输入框。
$('input').on('keyup', function(event){
if(event.keyCode == 13){ // 13 is the keycode for enter button
$(this).next('input').focus();
}
});
https://jsfiddle.net/jat1merL/
你在找这个吗?
顺便说一下,使用键向上而不是按键。 如果按住某个键,它会以您无法处理的速度触发大量按键事件;)