无论父级如何,查找相同类型的上一个元素

时间:2015-05-19 17:39:28

标签: javascript html css

我希望能够找到某个类型的前一个元素,无论它是否包含在同一个父元素中。

在这种情况下,我想找到之前的input[type="text"]元素并给予关注。

目前我可以在同一个父级中选择上一个兄弟,但希望能够将其过滤到仅input[type="text"]个元素,并允许前一个父级。

接受的答案仅为vanilla javascript。



document.addEventListener('keydown', function(e) {
  // if backspace is pressed and the input is empty
  if (e.keyCode === 8 && e.target.value.length === 0) {
    // This should give focus to the previous input element
    e.target.previousSibling.previousSibling.focus();
  }
}, false);

<div>
  <input type="text">
  <input type="text">
</div>
<div>
  <input type="text">
  <input type="text">
</div>
<div>
  <input type="text">
  <input type="text">
</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:5)

您可以使用querySelectorAll获取所有匹配元素,然后循环查找您所在的元素,然后将焦点放在上一个元素上。 querySelectorAll的结果是&#34;文档顺序&#34;。

&#13;
&#13;
document.addEventListener('keydown', function(e) {
  if (e.keyCode === 8 && e.target.value.length === 0) {
    // This should give focus to the previous input element
    var inputs = document.querySelectorAll('input[type="text"]');

    for(var i = 1; i < inputs.length; i++){
        if(inputs[i] == e.target){
            inputs[i-1].focus();
            break;
        }
    }
  }
}, false);
&#13;
<div>
  <input type="text">
  <input type="text">
</div>
<div>
  <input type="text">
  <input type="text">
</div>
<div>
  <input type="text">
  <input type="text">
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

您可以使用以下方法,而不是侦听文档上发生的所有事件,查找在某些元素上触发的事件。

选择并缓存包含要循环的元素的范围元素。

从我们之前在列表中选择的范围中选择并缓存您要循环的所有元素。

在循环的每次迭代中循环遍历列表中的所有元素:

  1. 使用立即调用的函数表达式(IIFE)创建一个新的词法范围,您可以在其中存储与该范围中当前元素关联的索引。
  2. 将事件监听器分配给&#39; keydown&#39;该元素的事件,您检查是否按下了退格键并且该字段为空;如果这些检查通过:
    • 将焦点设置在先前选择的元素列表中的前一个元素上;
    • 或者,如果当前元素是列表中的第一个元素,请将焦点设置在列表中的最后一个元素上。
  3. 使用此方法:

    • 您只查询DOM两次(在有限的范围内),
    • 您没有收听针对整个文档中每个元素触发的每个keydown事件,
    • 你可以通过从开始到结束循环来无限循环。

    &#13;
    &#13;
    var scope = document.querySelector('.scope');
    var inputs = scope.querySelectorAll('input[type="text"]');
    for (var i in Object.keys(inputs)) (function(index){
        inputs[i].addEventListener('keydown', function(e){
            if (e.which === 8 && this.value.length === 0) {
                var next = index - 1;
                if (next < 0) next = inputs.length - 1;
                inputs[next].focus();
            }
        }, false);
    })(i);
    &#13;
    <div class="scope">
        <div><input type="text"><input type="text"></div>
        <div><input type="text"><input type="text"></div>
        <div><input type="text"><input type="text"></div>
    </div>
    &#13;
    &#13;
    &#13;