Pozioma Lista rozwijana dla kilku elementów

0

Cześć,
Jestem początkujący w javascriptcie jak i nowym użytkownikiem forum. Mam problem ze stworzeniem prostej poziomem listy rozwijanej(pewne rzeczy już działają) a konkretnie chcę by np. przy kliknięciu na nagłówek 1 jego lista się rozwinęła, natomiast gdy kliknę w nagłówek 2 to chcę by lista nagłówka 1 się zwinęła a lista nagłówka 2 rozwinęła. W konsoli widzę, że odwołuje się do dobrych elementów do, których chcę dodać klasę "Hide"(klasa zwija daną listę) natomiast nie działa to jak sobie założyłem.
Proszę o pomoc w modyfikacji mojego kodu bądź naprowadzenie mnie jak to zrobić. Poniżej mój kod html i javascript.

<div class="menu-down">

      <ul>
        <li class="Btns"><a class="Target" href="#cateogry1"> category1</a>
          <ul class="ListFormat ListShow Hide">
            <li>test1</li>
            <li>test2</li>
            <li>test3</li>
          </ul>

        </li>

        <li class="Btns"><a class="Target" href="#category2">category2</a>
          <ul class="ListFormat ListShow Hide">
            <li>1</li>
            <li>2</li>
            <li>3</li>
          </ul>
        </li>

      </ul>
    </div>

const buttons = document.querySelectorAll(".Btns");

buttons.forEach(function (btn) {
  const button1 = btn.querySelector(".ListShow");
  // const button2 = btn.children[1]

  btn.addEventListener("click", function (btnEvent) {
    let CurrentButton = btnEvent.currentTarget.children[1];

    console.log(button1);

    buttons.forEach(function (item) {
      console.log(btn.children[1]);

      // TO NIE DZIAŁA
      if (button1 !== CurrentButton) {
        button1.classList.add("Hide")
        CurrentButton.classList.remove("Hide")
      }
    });

    // PO KLIKNIĘCIU LISTA SIĘ ROZWIJA PONOWNE KLIKNIĘCIE ZWIJA LISTĘ
    let Showbutton = btnEvent.currentTarget.children;
    for (i = 0; i < Showbutton.length; i++) {
      if (Showbutton[i].classList.contains("ListShow")) {
        Showbutton[i].classList.toggle("Hide");
      }
    }
  });
});

//JEŚLI KLIKAMY POZA LISTĄ ROZWIJANĄ LISTA SIĘ ZWIJA
window.addEventListener("click", function (event) {
  if (!event.target.matches(".Target")) {
    let dropdown = document.getElementsByClassName("ListShow");

    for (i = 0; i < dropdown.length; i++) {
      let openDropdown = dropdown[i];
      if (!openDropdown.classList.contains("Hide")) {
        openDropdown.classList.add("Hide");
      }
    }
  }
});
3
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>

<style>
  INPUT[type=radio] {display:none;}
  INPUT[type="radio"] ~ UL {display:none;}
  INPUT[type="radio"]:checked ~ UL {display:block;}
</style>
</head>
<body>

<div class="menu-down">
  <div>
    <input type="radio" name="menu" id="m1"><label for="m1">category1</label>
    <ul>
      <li>test1</li>
      <li>test2</li>
      <li>test3</li>
    </ul>
  </div>
  <div>
    <input type="radio" name="menu" id="m2"><label for="m2">category2</label>
    <ul class="ListFormat ListShow Hide">
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>
  </div>
</div>
    
</body>
</html>
0

@Freja Draco: Niestety nie wiem jak to się ma do mojego kodu javascript i jak mi to ma pomóc ale dzięki za chęci.@Freja Draco:

0

@Bruce17: Powyższe robi skutecznie za pomocą 3 linii CSS coś, co ty chcesz robić kulkudziesięciomia liniami JS.

0

Niemniej jeśli upierasz się, żeby robić to jednak dłuższą metodą, to:

if (button1 !== CurrentButton) 

CurrentButton ma zawsze tę samą wartość, a to ponieważ łapiesz go za pomocą ustawionego na sztywno indeksu:

let CurrentButton = btnEvent.currentTarget.children[1];

Możliwe, że są jeszcze inne błędy.

0

Upieram się by zrobić to w JS bo chcę powoli się tego języka uczyć.
Tak wiem, że CurrentButton jest na sztywno. Można by to zrobić dynamicznie wrzucić CurrentButton do pętli i sprawdzić który element CurrentButton[i] zawiera klasę np "ListShow" tak bym mógł do niego dodać/ klasę Hide. Niestety to również nie działa. Chciałem to zrobić przy pomocy foreach bo w domyśle zamierzam by tam było wiele przycisków ale coś pokręciłem parametrami w tej funkcji. I podejrzewam, że gdybym miał 20 przycisków to w css tych linijek było by o wiele wiecęj.
Odnosząc się do Twojego kodu to ok klikanie na jeden nagłówek zwija drugi, ale przy ponownym kliknięciu na ten sam nagłówek nic się nie dzieje, przy kliknięciu na wolne pole kiedy jakiś nagłówek jest rozwinięty też nic się nie dzieje, więc na niewiele mi się takie rozwiązanie przyda.
W każdym razie dziękuje, że poświęciłaś swój czas na pomoc. Ja będę szukał rozwiązania dalej. Pozdrawiam.

2

Masz:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>

<style>
.menuDown {border:1px solid green;}
.ListFormat {display:none;}
.Show + UL  {display:block;}
</style>
</head>
<body>

<div class="menuDown">
  <ul>
  
    <li class="Btns"><a class="Target" href="#cateogry1"> category1</a>
      <ul class="ListFormat">
        <li>test1</li>
        <li>test2</li>
        <li>test3</li>
      </ul>

    </li>

    <li class="Btns"><a class="Target" href="#category2">category2</a>
      <ul class="ListFormat">
        <li>1</li>
        <li>2</li>
        <li>3</li>
      </ul>
    </li>

  </ul>
</div>

<script>
// funkcja: pokaż / ukryj
function showHide(e) {
  Targets.forEach(function (item) {
    item.classList.remove("Show");
    if ((e.target.href) && (e.target.href==item.href)) e.target.classList.add("Show");
  });
}


// złap obiekty
const Targets = document.querySelectorAll(".Target");


// przypisz zdarzenia
Targets.forEach(function(el) {el.addEventListener("click", showHide);})
window.addEventListener("click", showHide);
document.querySelector(".menuDown").addEventListener("click", function(e) {e.stopPropagation();}, false);
</script>
</body>
</html>
0

Dziękuje, to się na pewno przyda.

1 użytkowników online, w tym zalogowanych: 0, gości: 1