简体   繁体   English

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

[英]Find previous element of same type regardless of parent

I would like to be able to find the previous element of a certain type, whether it is contained within the same parent or not. 我希望能够找到某个类型的前一个元素,无论它是否包含在同一个父元素中。

In this situation I want to find the previous input[type="text"] element and give it focus. 在这种情况下,我想找到以前的input[type="text"]元素并给它焦点。

Currently I can select the previous sibling in the same parent, but would like to be able to filter that to only input[type="text"] elements and allow the previous parent as well. 目前我可以选择同一父节点中的前一个兄弟节点,但希望能够将其过滤为仅input[type="text"]元素并允许前一个父节点。

The accepted answer will be vanilla javascript only. 接受的答案只是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> 

You could just use querySelectorAll to get all matching elements and then loop to find the one you are in, then focus the previous. 您可以使用querySelectorAll获取所有匹配的元素,然后循环查找您所在的元素,然后将焦点放在上一个元素上。 The result of querySelectorAll is in "document order". querySelectorAll的结果是“文档顺序”。

 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); 
 <div> <input type="text"> <input type="text"> </div> <div> <input type="text"> <input type="text"> </div> <div> <input type="text"> <input type="text"> </div> 

Instead of listening to all events occurring on the document, looking for events triggered on certain elements, you can use the following method. 您可以使用以下方法,而不是侦听文档上发生的所有事件,查找在某些元素上触发的事件。

Select and cache the scope element which contains the elements you want to cycle through. 选择并缓存包含要循环的元素的范围元素。

Select and cache all of the elements you want to cycle through from the scope we selected previously in a list. 从我们之前在列表中选择的范围中选择并缓存您要循环的所有元素。

Loop through all of the elements in the list, in each iteration of the loop: 在循环的每次迭代中循环遍历列表中的所有元素:

  1. Use an Immediately Invoked Function Expression (IIFE) to create a new lexical scope where you can store the index associated with the current element in that scope. 使用立即调用的函数表达式(IIFE)创建一个新的词法范围,您可以在其中存储与该范围中的当前元素关联的索引。
  2. Assign an event listener to the 'keydown' event for that element where you check to see if the backspace key was pressed and the field is empty; 将事件侦听器分配给该元素的'keydown'事件,在该事件中检查是否按下了退格键并且字段为空; if these checks pass either: 如果这些检查通过:
    • set the focus on the previous element in the list of elements previously selected; 将焦点设置在先前选择的元素列表中的前一个元素上;
    • or, if the current element is the first element in the list, set the focus on the last element in the list. 或者,如果当前元素是列表中的第一个元素,则将焦点设置在列表中的最后一个元素上。

Using this method: 使用此方法:

  • you only query the DOM twice (in a limited scope), 你只查询DOM两次(在有限的范围内),
  • you aren't listening to every keydown event fired on every element in the entire document, and 您没有收听对整个文档中的每个元素触发的每个keydown事件,以及
  • you can cycle infinitely by looping from the beginning to the end. 你可以通过从开始到结束的循环无限循环。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM