2015-05-19 21 views
5

Chciałbym móc znaleźć poprzedni element określonego typu, czy jest on zawarty w tym samym rodzica, czy nie.Znajdź poprzedni element tego samego typu, niezależnie od rodzica

W tej sytuacji chcę znaleźć poprzedni element input[type="text"] i nadać mu ostrość.

Obecnie mogę wybrać poprzedniego rodzeństwo w tym samym rodzica, ale chciałbym, aby móc filtrować to tylko do elementów input[type="text"] i umożliwić również poprzedniego rodzica.

Zaakceptowana odpowiedź będzie tylko javascript wanilią.

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>

+1

Używasz jQuery czy jest to czysty javascript? – wahwahwah

Odpowiedz

5

mógłby po prostu użyć querySelectorAll aby wszystkie elementy dopasowane, a następnie pętlę, aby znaleźć taki jesteś w, następnie skup się na poprzednim. Wynik querySelectorAll jest w "kolejności dokumentów".

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>

+0

Z pewnością dobry pomysł, jeśli elementy nie są dynamiczne. –

-1

użycie

e.target.previousElementSibling.previousElementSibling.focus() 

zamiast korzystania previousSibling

2

Zamiast słuchać wszystkich zdarzeń występujących na dokumencie, patrząc na wydarzenia wyzwalane na niektóre elementy, można użyć następującej metody.

Wybierz i buforuj element zakresu, który zawiera elementy, które chcesz przełączyć.

Wybierz i buforuj wszystkie elementy, które chcesz przełączyć z zakresu wybranego wcześniej na liście.

Pętla przez wszystkie elementy na liście, w każdej iteracji pętli:

  1. użyć natychmiast wywoływane wyrażenie funkcyjne (Iife), aby utworzyć nowy zakres leksykalny w której można przechowywać indeksu związanego z obecny element w tym zakresie.
  2. Przypisz detektor zdarzeń do zdarzenia "keydown" dla tego elementu, gdzie sprawdzasz, czy klawisz Backspace został naciśnięty i pole jest puste; jeśli te kontrole przejdą:
    • ustaw fokus na poprzednim elemencie na liście wcześniej wybranych elementów;
    • lub, jeśli bieżący element jest pierwszym elementem na liście, ustaw fokus na ostatnim elemencie na liście.

Stosując tę ​​metodę:

  • tylko zapytania DOM dwukrotnie (w ograniczonym zakresie),
  • ty nie słuchasz każdego keyDown zwolniony na każdy element cały dokument, i
  • można cyklicznie przechodzić w pętli od początku do końca.

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>

Powiązane problemy