【问题标题】:How do I make "Enter" keypress in an <input> Element shift focus to the next <input> element on the page. (JavaScript)如何使 <input> 元素中的“Enter”键将焦点转移到页面上的下一个 <input> 元素。 (JavaScript)
【发布时间】:2017-04-12 04:51:22
【问题描述】:

如何在 &lt;input&gt; 元素中按下 Enter 键将焦点转移到页面上的下一个 &lt;input&gt; 元素?

我有一个 for 循环,它创建 &lt;li&gt; 元素,其中包含 &lt;input&gt; 元素。我需要这样做,当用户在键盘上按 Enter 键时,网站将专注于下一个输入字段,以便用户可以输入下一个玩家名称,而无需在使用鼠标和键盘之间切换。

我认为使用nextSibling 属性是解决方案,但它不会起作用,因为&lt;input&gt; 元素在技术上没有任何兄弟姐妹,因为它们每个都在内部/是不同&lt;li&gt; 元素的子元素。

这是我的 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 循环运行后可以达到的最大数字。

【问题讨论】:

  • 你需要了解闭包。

标签: javascript


【解决方案1】:

问题:

您的实际代码的问题是i 在事件处理程序callback 函数中始终等于numberOfPlayers+1,因此您试图专注于null 元素,您可以阅读有关@987654321 的更多信息@看看为什么i总是等于numberOfPlayers+1

解决方案:

首先你需要在你的输入上使用onkeypress事件,然后测试按下的键是否是Enter,如果按下则获取当前inputid,解压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();
         }
    }
});

这是一个有效的 sn-p:

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();
      }
    }
  });
}
&lt;ul id="name-list"&gt;&lt;/ul&gt;

【讨论】:

  • 这会在最后一个输入框之后引发错误。 "message": "Uncaught TypeError: Cannot read property 'focus' of null", 你需要检查 null 那里。
  • @jrook 很好地指出了我的朋友,我编辑了我的答案以添加 i 的测试。
  • 错误是因为 if 语句应该是 "
【解决方案2】:

如果你想坚持使用 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);
}

【讨论】:

    【解决方案3】:

    这是我的解决方案。

    不要忘记创建的&lt;li&gt; 元素需要附加到&lt;body&gt; 之类的东西上。我实际上添加了一个&lt;ul&gt; 元素并将其附加到&lt;body&gt;,然后将&lt;li&gt; 元素附加到&lt;ul&gt; 元素。

    如果使用nextSibling,则不需要将元素保留在nameInputArray 中。我没有删除它来展示它应该如何被初始化,然后你才能在你的循环中使用它。此外,nextSibling 在我的解决方案中有效,因为我已将所有&lt;li&gt;s 放在一个&lt;ul&gt; 下,我认为这是the correct thing to do anyway

    除此之外,我只是在这里和那里纠正了一些事情。如果您对此代码有更多疑问,请告诉我。

    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;
    }

    更新:从父&lt;li&gt;元素获取每个输入框:

    在 OP 发表评论后,我看到他们想要这样的结构:

    <ul>
        <li>input box1</li>
        <li>input box2</li>
        <li>input box3</li>
    </ul>
    

    在这个结构中,每个输入框都是其父&lt;li&gt;元素的第一个子节点。因此,我们仍然可以这样使用nextSibling(作为OP打算使用的):

    nextInput = event.target.parentElement.nextSibling.childNodes[0];
    

    这一行首先找到父&lt;li&gt;元素,应用nextSibling获取下一个li元素,然后获取该元素内的输入框。

    【讨论】:

    • 非常感谢,我确实有一个
        作为
      • 元素的父级。在我的代码中,这就是以下行的用途: document.getElementById('name-list').appendChild(liElement);
    • 所以我想我的问题是:关注下一个 li 与关注下一个输入是一样的吗?
    • @Osuriel:我不确定你为什么要这样做。但我认为你不能专注于&lt;li&gt; 元素,除非you define a tabIndex for them
    • 如果您想更改您的问题,请考虑将其作为新问题发布(例如后续问题)。此外,如果他们解决了问题,请考虑接受其中一个答案,以便其他访问者可以从中受益。
    • @Osuriel:我更新了我的代码。现在每个输入元素都在自己的&lt;li&gt; 中。我们仍然可以使用nextSibling,但我们需要先获取父元素,这就是 updated 代码所做的。
    【解决方案4】:
    $('input').on('keyup', function(event){
      if(event.keyCode == 13){ // 13 is the keycode for enter button
        $(this).next('input').focus();
      }
    });
    

    https://jsfiddle.net/jat1merL/

    你在找这个吗?

    顺便说一句,使用 keyup 而不是 keypress。如果按住某个键,它会以您无法处理的速度触发大量按键事件;)

    【讨论】:

    • 谢谢,但这不起作用,因为输入在
    • 元素内。还是非常感谢。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签