• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Poprawa kodu

0 głosów
442 wizyt
pytanie zadane 30 maja 2017 w JavaScript przez nitrio578 Początkujący (270 p.)

Napisałem kod. który działa, ale jest patologiczny, że tak powiem. Chciałbym zrobić tak żeby nie było w nim powtórzeń, jest to kod z rozwijanym menu. Próbowałem  za pomocą querySelectorAll łapać listy ul i li, ale wtedy to nie działało.

$(document).ready(function() {



$('#menu3').click(function  () { 
	$('.3').slideToggle(300);
});
$('#menu2').click(function  () { 
	$('.2').slideToggle(300);
});
$('#menu1').click(function  () { 
	$('.1').slideToggle(300);
});


});

 

komentarz 30 maja 2017 przez ScriptyChris Mędrzec (190,190 p.)

Pokaż jeszcze kod HTML. Bo jeśli #menu1, #menu2 i #menu3 mają tego samego rodzica, to warto zastosować tutaj EventDelegation.

komentarz 1 czerwca 2017 przez nitrio578 Początkujący (270 p.)

Próbowałem to zrobić tylko, że nie działa. Poniżej wrzucam kod z HTML-a i JS.

$(document).ready(function() {

$('#menu').on("click",'ul',function(event) {
var elem =  $(event.id);
if(elem.is('ul')) {
    
elem.slideToggle(300);
}
});



});

<!DOCTYPE>
<html lang="pl">

<head> 
<meta charset= "UTF-8"/>
<link rel="stylesheet" href="style.css" type="text/css" />
<link href="https://fonts.googleapis.com/css?family=Lobster" rel="stylesheet"> 



</head>
<body>

</div>
<ol id="menu"> 
<ul id = "menu1">magna sagittis
<li> sit amet</li>
</ul>
 <ul id ="menu2">aretra tempor. Suspendisse potenti.
 <li>n ut ante dignissim m </li>
 <li> utate at nunc vel, </li>
 </ul>
<ul id = "menu3"> In eu rhoncus ipsu
<li>tincidunt eget elit</li>
<li>consectetur adipiscin</li>
<li>cinula mole</li>
</ul>
 </ol>
</body>

</html>

 

komentarz 1 czerwca 2017 przez ScriptyChris Mędrzec (190,190 p.)

Spróbuj tego:

$("#menu").on("click", "ul", function(event) {
  var elem = $(event.target);

  if (elem.is("li")) {
    elem.slideToggle(300);
  }
});

W razie czego dodaj $(document).ready()

komentarz 2 czerwca 2017 przez nitrio578 Początkujący (270 p.)

Działa tylko jest parę problemów, po pierwsze gdy kliknę na element z listy li to chowa po jednym, a ja chcę żeby chowało wszystko oprócz tego głównego ul, który jest kliknięty w tym momencie. Próbowałem z not, ale nie zwijało całe menu.

$("#menu").on("click", "ul", function(event) {
  var elem = $(event.target);
 
  if (elem.is("ul")) {
      
    elem.not("ul").slideToggle(300);
    
  }
});

 

komentarz 2 czerwca 2017 przez ScriptyChris Mędrzec (190,190 p.)

chcę żeby chowało wszystko oprócz tego głównego ul

Czyli chcesz, aby kliknięcie w którykolwiek element listy zwijało ją całą (wszystkie <li> na raz)?

komentarz 2 czerwca 2017 przez nitrio578 Początkujący (270 p.)
Znaczy jak kliknę na element listy ul to chcę żeby te elementy, które do niego należą zwinęły się, ale żeby ul zostało, a nie zwinęło się.

Czyli np jak jest ten fragment kodu

<ul id ="menu2">aretra tempor. Suspendisse potenti.

 <li>n ut ante dignissim m </li>

 <li> utate at nunc vel, </li>

 </ul>

to naduszenie na ul zwnie wszystko pod tym, ale tak żeby ul nie zostało zwinięte
komentarz 2 czerwca 2017 przez ScriptyChris Mędrzec (190,190 p.)
edycja 2 czerwca 2017 przez ScriptyChris

Do tego nie potrzeba Ci raczej sprawdzania, w co konkretnie kliknąłeś. Wystarczy zostawić listener na <ul> i po prostu przy kliknięciu w cokolwiek w jego obrębie, ukryć wszystkie <li> za pomocą pętli:

/*
    $("#menu").on("click", "ul", function(event) {
      $("li").each(function(idx, listItem) {
        $(listItem).slideToggle(300);
      });
    });
*/

W takim razie możesz odnieść się poprzez event.currentTarget do elementu <ul>, w obrębie którego kliknąłeś. Potem pętla zwinąć wszystkie elementy <li> z okreslonego <ul>

$("#menu").on("click", "ul", function(event) {
  $(event.currentTarget).each(function(idx, listItem) {
    $(listItem).slideToggle(300);
  });
});

Dopiero teraz zauważyłem, że masz główny element <ol> a w nim kilka <ul> i dopiero tam <li>.

P.S. Nie powinieneś umieszczać innych elementów niż <li> bezpośrednio wewnątrz <ul> bądź <ol>, tak jak robisz to np. tu:

<ul id="menu1">magna sagittis
    <li> sit amet</li>
  </ul>

https://developer.mozilla.org/en/docs/Web/HTML/Element/ul

https://developer.mozilla.org/en/docs/Web/HTML/Element/ol

, ponieważ możesz tam umieszczać jedynie elementy <li>:

Permitted content Zero or more <li> elements, which in turn often contain nested <ol> or <ul> elements.
komentarz 2 czerwca 2017 przez nitrio578 Początkujący (270 p.)
edycja 2 czerwca 2017 przez nitrio578
Dzięki teraz działa tak jak powinno i jeszcze jedno co to jest te "idx" w each(function(idx, listItem)  ?
komentarz 2 czerwca 2017 przez ScriptyChris Mędrzec (190,190 p.)

co to jest te "idx" w each(function(idx, listItem)  ?

Wystarczy przeczytać w dokumentacji https://api.jquery.com/each/

function

Type: FunctionInteger index, Element element )

, pierwszym argumentem jest indeks aktualnie iterowanego elementu, a drugim tenże element. Żeby otrzymać element jako argument, trzeba najpierw podać indeks, gdyż w takiej kolejności przekazywane są parametry podczas wywoływania callback'a. Można zajrzeć do source code jQuery :)

https://github.com/jquery/jquery/blob/master/src/core.js#L92

+

https://github.com/jquery/jquery/blob/master/src/core.js#L297

Konkretnie ten fragment, jeśli chodzi o .each() na elemencie DOM:

https://github.com/jquery/jquery/blob/master/src/core.js#L303

3 odpowiedzi

0 głosów
odpowiedź 30 maja 2017 przez Chess Szeryf (76,730 p.)
edycja 30 maja 2017 przez Chess
var menu1 = document.getElementById('menu1');
// var hidden_element = document.getElementById('hidden_element');
function dropdown(){
   // ... 
   // hidden_element.style.display = 'block';
}

menu1.addEventListener('click',dropdown,false);

Napisz jaki chcesz osiągnąć efekt.

0 głosów
odpowiedź 30 maja 2017 przez Artek Stary wyjadacz (11,800 p.)
menu#1, menu#2, menu#3 daj im jedną klasę np. menu-buttons.

Podepnij onclick pod klasę menu-buttons. Teraz niech np. to co ma być pod slideToggle ma id takie samo jak ostatni znak id elementu klasy menu-buttons. Wydobywasz ostatni znak z $(this) i wiesz co ma się rozwijać. No chodzi o to aby nazwa elementu wywołującego zdarzenie była jakoś powiązana z tym co ma być rozwijane.
0 głosów
odpowiedź 31 maja 2017 przez Radekol Bywalec (2,880 p.)
No ja bym użył Event Delegation. Czyli chwytasz rodzica tych menu1, menu2, menu3 i wtedy tworzysz jedną funkce która czyta który obiekt (dziecko tego rodzica) został kliknięty. Polecam! :)

Podobne pytania

0 głosów
2 odpowiedzi 449 wizyt
pytanie zadane 11 marca 2020 w JavaScript przez PoProstuTomasz Początkujący (470 p.)
0 głosów
1 odpowiedź 187 wizyt
pytanie zadane 16 kwietnia 2019 w JavaScript przez Mateo13 Bywalec (2,360 p.)
0 głosów
0 odpowiedzi 215 wizyt
pytanie zadane 28 lipca 2017 w JavaScript przez UltraSF Stary wyjadacz (11,740 p.)

93,604 zapytań

142,529 odpowiedzi

322,996 komentarzy

63,092 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Kursy INF.02 i INF.03
...