Hur gör jag detta på rätt sätt? (javascript)

Trädvy Permalänk
Medlem
Plats
Piteå
Registrerad
Okt 2004

Hur gör jag detta på rätt sätt? (javascript)

Hej,
Jag sitter och försöker lära mig lite javascript, mest trial and error.
Just nu knåpar jag på en dropdown meny.

Såhär ser koden ut atm:

Javascript:

function dropdown() { var dropdownTrigger = document.getElementById("dd"); var dropdownTrigger2 = document.getElementById("dd2"); var dropdownTrigger3 = document.getElementById("dd3"); var dropdownTrigger4 = document.getElementById("dd4"); if (dropdownTrigger.style.display == "none") { dropdownTrigger.style.display="block"; dropdownTrigger2.style.display="none"; dropdownTrigger3.style.display="none"; dropdownTrigger4.style.display="none"; } else { dropdownTrigger.style.display="none"; } } function dropdown2() { var dropdownTrigger = document.getElementById("dd"); var dropdownTrigger2 = document.getElementById("dd2"); var dropdownTrigger3 = document.getElementById("dd3"); var dropdownTrigger4 = document.getElementById("dd4"); if (dropdownTrigger2.style.display == "none") { dropdownTrigger.style.display="none"; dropdownTrigger2.style.display="block"; dropdownTrigger3.style.display="none"; dropdownTrigger4.style.display="none"; } else { dropdownTrigger2.style.display="none"; } } function dropdown3() { var dropdownTrigger = document.getElementById("dd"); var dropdownTrigger2 = document.getElementById("dd2"); var dropdownTrigger3 = document.getElementById("dd3"); var dropdownTrigger4 = document.getElementById("dd4"); if (dropdownTrigger3.style.display == "none") { dropdownTrigger.style.display="none"; dropdownTrigger2.style.display="none"; dropdownTrigger3.style.display="block"; dropdownTrigger4.style.display="none"; } else { dropdownTrigger3.style.display="none"; } } function dropdown4() { var dropdownTrigger = document.getElementById("dd"); var dropdownTrigger2 = document.getElementById("dd2"); var dropdownTrigger3 = document.getElementById("dd3"); var dropdownTrigger4 = document.getElementById("dd4"); if (dropdownTrigger4.style.display == "none") { dropdownTrigger.style.display="none"; dropdownTrigger2.style.display="none"; dropdownTrigger3.style.display="none"; dropdownTrigger4.style.display="block"; } else { dropdownTrigger4.style.display="none"; } } function dropdownAll() { var ddaText = document.getElementById("dda"); var dropdownTrigger1 = document.getElementById("dd"); var dropdownTrigger2 = document.getElementById("dd2"); var dropdownTrigger3 = document.getElementById("dd3"); var dropdownTrigger4 = document.getElementById("dd4"); if (ddaText.innerHTML == "Open all"){ ddaText.innerHTML = "Hide all"; dropdownTrigger1.style.display="block"; dropdownTrigger2.style.display="block"; dropdownTrigger3.style.display="block"; dropdownTrigger4.style.display="block"; } else { ddaText.innerHTML = "Open all"; dropdownTrigger1.style.display="none"; dropdownTrigger2.style.display="none"; dropdownTrigger3.style.display="none"; dropdownTrigger4.style.display="none"; } }

HTML:

<div class="left-menu"> <p>Menu</p> <br> <a href="#" onclick="dropdown()"> +Menu 1</a> <ul id="dd" style="display:none;"> <li><a href="#">item 1:1</a></li> <li><a href="#">item 1:2</a></li> <li><a href="#">item 1:3</a></li> <li><a href="#">item 1:4</a></li> </ul> <a href="#" onclick="dropdown2()"> +Menu 2</a> <ul id="dd2" class="dropdown" style="display:none;"> <li><a href="#">item 2:1</a></li> <li><a href="#">item 2:2</a></li> <li><a href="#">item 2:3</a></li> <li><a href="#">item 2:4</a></li> </ul> <a href="#" onclick="dropdown3()"> +Menu 3</a> <ul id="dd3" class="dropdown" style="display:none;"> <li><a href="#">item 3:1</a></li> <li><a href="#">item 3:2</a></li> <li><a href="#">item 3:3</a></li> <li><a href="#">item 3:4</a></li> </ul> <a href="#" onclick="dropdown4()"> +Menu 4</a> <ul id="dd4" class="dropdown" style="display:none;"> <li><a href="#">item 4:1</a></li> <li><a href="#">item 4:2</a></li> <li><a href="#">item 4:3</a></li> <li><a href="#">item 4:4</a></li> </ul> <a href="#" id="dda" onclick="dropdownAll()">Open all</a> </div>

Det fungerar precis som jag vill men det känns absolut inte som jag har gjort det på bästa sättet, snarare tvärtom.

Hur hade ni som kan gått tillväga?

CPU: AMD Ryzen 1700x @ 3.8GHz || Mem: 16GB Corsair LPX 3000mhz || Mobo: Asus x370 Prime || GPU: EVGA Geforce GTX1070 SC || SSD: WD black 500GB m2 || OS: Linux Mint/Win 10 || Monitor: Dell 43" 4K P4317Q

Citera om du vill ha svar :)

Trädvy Permalänk
Medlem
Plats
Skövde
Registrerad
Okt 2014

Tjena!

Ser rätt så omständigt ut att göra det så som du har gjort det, som du själv säger. Har inte gjort det i Javascript innan, men har gjort nån drop down meny i CSS innan, och det var helt klart mindre kod. Dock så är det drop down i en vertikal meny, men det funkar säkert på liknande sätt om man skulle vilja ha det i en horizontal. Mitt exempel kan du se här om du hovrar över "tutorials".

Ledsen att jag inte kan svara på din fråga direkt, men ville bara tipsa om CSS (ifall du inte hade sett det innan) då det var ganska smidigt. Vill du ha koden för det kan jag försöka peta ut den biten som hör till det

Stationär: MSI Gaming GTX 980ti | MSI Z97 Gaming 5 | Intel i5 4690K | 3TB lagring | 16GB RAM
Laptop: HP ProBook 6460b - Linux Ubuntu 16.04

Trädvy Permalänk
Medlem
Registrerad
Jan 2009

Kan man inte ha en funktion i javascript koden som du sedan skickar in en parameter till (typ, 1,2,3,4,all) ? sedan typ en for-loop i funktionen?

Om det nu är kortare kod du vill skriva.

Trädvy Permalänk
Medlem
Plats
Piteå
Registrerad
Okt 2004
Skrivet av wahlmat:

Tjena!

Ser rätt så omständigt ut att göra det så som du har gjort det, som du själv säger. Har inte gjort det i Javascript innan, men har gjort nån drop down meny i CSS innan, och det var helt klart mindre kod. Dock så är det drop down i en vertikal meny, men det funkar säkert på liknande sätt om man skulle vilja ha det i en horizontal. Mitt exempel kan du se här om du hovrar över "tutorials".

Ledsen att jag inte kan svara på din fråga direkt, men ville bara tipsa om CSS (ifall du inte hade sett det innan) då det var ganska smidigt. Vill du ha koden för det kan jag försöka peta ut den biten som hör till det

Jo det är ju aningen krångligt sätt jag gjort det på, det bör finnas mycket enklare väg att gå
Coolt om det är helt i css! jag försöker jag ta mig framåt i javascript och senare jquery just nu.

CPU: AMD Ryzen 1700x @ 3.8GHz || Mem: 16GB Corsair LPX 3000mhz || Mobo: Asus x370 Prime || GPU: EVGA Geforce GTX1070 SC || SSD: WD black 500GB m2 || OS: Linux Mint/Win 10 || Monitor: Dell 43" 4K P4317Q

Citera om du vill ha svar :)

Trädvy Permalänk
Medlem
Plats
Piteå
Registrerad
Okt 2004
Skrivet av Tompanhuhu:

Kan man inte ha en funktion i javascript koden som du sedan skickar in en parameter till (typ, 1,2,3,4,all) ? sedan typ en for-loop i funktionen?

Om det nu är kortare kod du vill skriva.

Ja jo det är något sådant jag tänkte faktiskt men jag vet inte riktigt hur jag gör det i praktiken. Har du tips på någon bra sida där man kan lära sig detta? w3schools gillar jag inte riktigt..

CPU: AMD Ryzen 1700x @ 3.8GHz || Mem: 16GB Corsair LPX 3000mhz || Mobo: Asus x370 Prime || GPU: EVGA Geforce GTX1070 SC || SSD: WD black 500GB m2 || OS: Linux Mint/Win 10 || Monitor: Dell 43" 4K P4317Q

Citera om du vill ha svar :)

Trädvy Permalänk
Medlem
Registrerad
Jan 2009

www.codecademy.com kanske, men tror du måste gå javascript kursen från början till slut så det blir väldigt grundläggande i början

Trädvy Permalänk
Medlem
Plats
Piteå
Registrerad
Okt 2004
Skrivet av Tompanhuhu:

www.codecademy.com kanske, men tror du måste gå javascript kursen från början till slut så det blir väldigt grundläggande i början

Tack, jag ska kolla in den sidan

CPU: AMD Ryzen 1700x @ 3.8GHz || Mem: 16GB Corsair LPX 3000mhz || Mobo: Asus x370 Prime || GPU: EVGA Geforce GTX1070 SC || SSD: WD black 500GB m2 || OS: Linux Mint/Win 10 || Monitor: Dell 43" 4K P4317Q

Citera om du vill ha svar :)

Trädvy Permalänk
Medlem
Plats
Skövde
Registrerad
Okt 2014

Nu kom jag på nåt!

Använd dig av "events"! Då (tror jag) att du kan slippa alla klasser Vet inte om jag får alla syntaxer rätt nu, men det borde bli typ något liknande:

<button onmouseover="myFunction(event);" > myFunction{ var newVar = event.target.id; newVar (lägg på din CSS eller vad du nu vill ha här) ; }

Använder du events så får du för det elementet du är på, och kan göra "samma" sak. Alltså slipper du koda samma kod för 4 knappar om dom ska göra samma sak typ Min tanke är att du sätter alla 4 till "none" i sin CSS, sen att du sätter den med eventet till blocket (om det nu var det du använde) Hoppas detta kan ge någon hjälp

Stationär: MSI Gaming GTX 980ti | MSI Z97 Gaming 5 | Intel i5 4690K | 3TB lagring | 16GB RAM
Laptop: HP ProBook 6460b - Linux Ubuntu 16.04

Trädvy Permalänk
Medlem
Registrerad
Jun 2014

https://developer.mozilla.org/en-US/docs/Web/JavaScript (referensmaterial #1)

http://jsbin.com/boxeqozava/1/edit?html,js,output

bara 2 små saker som förminskar mängden kod avsevärt: loops och funktions-argument

loops
: arrays är numrerade listor (som den vi får via getELEMENTSbyclassname) och vi kan därför gå igenom varje element om vi vet hur lång listan är, vilket vi får reda på via .length (vi kan loopa utan att veta hur lång listan är också, men det är idealt om for-loopen vet precis när den ska stanna så slipper vi göra det manuellt)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refer...

det finns flera sorters loopar men vi använder i detta fall en for-loop. kan se lite komplicerad ut från början men det är bara att lära sig för den använder man mycket
https://developer.mozilla.org/en/docs/Web/JavaScript/Referenc...

funktions-argument: istället för att göra en helt ny funktion för varje dropdown så skickar vi istället ett värde(argument) vid varje funktions-anrop som indikerar just vilken dropdown vi klickat på

wahlmat är på god väg då events är bra sätt att identifera vart klicket hände (om man har samma funktion till flera onclicks), men i just detta fall är det lika enkelt att manuellt skriva in IDn

Trädvy Permalänk
Medlem
Registrerad
Jan 2009
Skrivet av pellle87:

Tack, jag ska kolla in den sidan

Aldrig pysslat med javascript, men efter att ha googlat lite syntax fick jag ihop detta.

function dropdown(slot) { var ddaText = document.getElementById("dda"); var dropdownTrigger = ["all","dd","dd2","dd3","dd4"]; if (slot == 0 && ddaText.innerHTML == "Open all"){ for (i = 1; i < dropdownTrigger.length; i++) { document.getElementById(dropdownTrigger[i]).style.display="block"; } ddaText.innerHTML = "Hide all"; } else if (slot == 0 && ddaText.innerHTML == "Hide All"){ for (i = 1; i < dropdownTrigger.length; i++) { document.getElementById(dropdownTrigger[i]).style.display="none"; } ddaText.innerHTML = "Open all"; } else { for (i = 1; i < dropdownTrigger.length; i++) { if (slot == i){ document.getElementById(dropdownTrigger[i]).style.display="block"; } else { document.getElementById(dropdownTrigger[i]).style.display="none"; } } } }

Ändrade även html filen lite, kolla här:
https://repl.it/En17/2

Det är ju mindre kod, men vettifan om det är mycket finare / lättare att läsa
Dock är koden väldigt dynamisk då du kan lägga till fler dropdowns genom att bara lägga in fler värden i arrayen.

Trädvy Permalänk
Medlem
Plats
Piteå
Registrerad
Okt 2004
Skrivet av Tompanhuhu:

Aldrig pysslat med javascript, men efter att ha googlat lite syntax fick jag ihop detta.

function dropdown(slot) { var ddaText = document.getElementById("dda"); var dropdownTrigger = ["all","dd","dd2","dd3","dd4"]; if (slot == 0 && ddaText.innerHTML == "Open all"){ for (i = 1; i < dropdownTrigger.length; i++) { document.getElementById(dropdownTrigger[i]).style.display="block"; } ddaText.innerHTML = "Hide all"; } else if (slot == 0 && ddaText.innerHTML == "Hide All"){ for (i = 1; i < dropdownTrigger.length; i++) { document.getElementById(dropdownTrigger[i]).style.display="none"; } ddaText.innerHTML = "Open all"; } else { for (i = 1; i < dropdownTrigger.length; i++) { if (slot == i){ document.getElementById(dropdownTrigger[i]).style.display="block"; } else { document.getElementById(dropdownTrigger[i]).style.display="none"; } } } }

Ändrade även html filen lite, kolla här:
https://repl.it/En17/2

Det är ju mindre kod, men vettifan om det är mycket finare / lättare att läsa
Dock är koden väldigt dynamisk då du kan lägga till fler dropdowns genom att bara lägga in fler värden i arrayen.

Ja det var ju helt klart mindre kod, däremot var den 3 resor värre att förstå som du säger Jag ska mixtra runt lite med detta och se vad jag kommer fram till.

Tack för att du tar dig tid!

CPU: AMD Ryzen 1700x @ 3.8GHz || Mem: 16GB Corsair LPX 3000mhz || Mobo: Asus x370 Prime || GPU: EVGA Geforce GTX1070 SC || SSD: WD black 500GB m2 || OS: Linux Mint/Win 10 || Monitor: Dell 43" 4K P4317Q

Citera om du vill ha svar :)

Trädvy Permalänk
Medlem
Plats
i din garderob
Registrerad
Sep 2007

Blev sugen på att labba lite med funktionell JavaScript. Här är en variant som använder klassnamn för att toggla menyer! http://codepen.io/anon/pen/QGVmBj

edit: Det råkade bli ett spel.. http://codepen.io/anon/pen/LbJJYg

Bilanaloger är som Volvo — varenda svenne kör med dem

Trädvy Permalänk
Medlem
Plats
Piteå
Registrerad
Okt 2004
Skrivet av Teknocide:

Blev sugen på att labba lite med funktionell JavaScript. Här är en variant som använder klassnamn för att toggla menyer! http://codepen.io/anon/pen/QGVmBj

edit: Det råkade bli ett spel.. http://codepen.io/anon/pen/LbJJYg

haha GW!

Sitter själv och pillrar på men har kört fast: http://codepen.io/anon/pen/pNOxbx
Betydligt kortare kod nu men just nu kan jag bara öppna menyerna, får inte till stängningen

CPU: AMD Ryzen 1700x @ 3.8GHz || Mem: 16GB Corsair LPX 3000mhz || Mobo: Asus x370 Prime || GPU: EVGA Geforce GTX1070 SC || SSD: WD black 500GB m2 || OS: Linux Mint/Win 10 || Monitor: Dell 43" 4K P4317Q

Citera om du vill ha svar :)

Trädvy Permalänk
Medlem
Registrerad
Jun 2014

for(i=0; i<drop.length; i++) drop[i].style.display = 'none';

Om du skippar {} så ingår endast 1:a raden i for loopen, du får inte ha en tom rad emellan. Likadant med if etc

Såg nu också att du råkade använda jämförelse operatorn(===) istället för assignment operatorn (=)

Trädvy Permalänk
Medlem
Plats
Piteå
Registrerad
Okt 2004
Skrivet av non_noutils:

for(i=0; i<drop.length; i++) drop[i].style.display = 'none';

Om du skippar {} så ingår endast 1:a raden i for loopen, du får inte ha en tom rad emellan. Likadant med if etc

Såg nu också att du råkade använda jämförelse operatorn(===) istället för assignment operatorn (=)

Ah okej, jag får ändå inte till det... måste hitta en javascript for dummies bok känns det som hah

CPU: AMD Ryzen 1700x @ 3.8GHz || Mem: 16GB Corsair LPX 3000mhz || Mobo: Asus x370 Prime || GPU: EVGA Geforce GTX1070 SC || SSD: WD black 500GB m2 || OS: Linux Mint/Win 10 || Monitor: Dell 43" 4K P4317Q

Citera om du vill ha svar :)

Trädvy Permalänk
Medlem
Plats
i din garderob
Registrerad
Sep 2007
Skrivet av pellle87:

haha GW!

Sitter själv och pillrar på men har kört fast: http://codepen.io/anon/pen/pNOxbx
Betydligt kortare kod nu men just nu kan jag bara öppna menyerna, får inte till stängningen

I din for-loop jämför du värdet med 'none' istället för att sätta det.

Bilanaloger är som Volvo — varenda svenne kör med dem

Trädvy Permalänk
Medlem
Plats
Piteå
Registrerad
Okt 2004
Skrivet av Teknocide:

I din for-loop jämför du värdet med 'none' istället för att sätta det.

joo så långt tror jag att jag hänger med, såhär ser det ut just nu:

function toggleDropdown(ddName) { var drop = document.getElementsByClassName('dropmenu'); for(i=0; i<drop.length; i++) { drop[i].style.display ='none'; document.getElementById(ddName).style.display='block'; } }

CPU: AMD Ryzen 1700x @ 3.8GHz || Mem: 16GB Corsair LPX 3000mhz || Mobo: Asus x370 Prime || GPU: EVGA Geforce GTX1070 SC || SSD: WD black 500GB m2 || OS: Linux Mint/Win 10 || Monitor: Dell 43" 4K P4317Q

Citera om du vill ha svar :)

Trädvy Permalänk
Medlem
Registrerad
Jun 2014
Skrivet av pellle87:

Ah okej, jag får ändå inte till det... måste hitta en javascript for dummies bok känns det som hah

programmering är inte så intuitivt ibland, man gör fler fel än rätt innan man blivit bekväm i skorna

korrigerade du båda mina kommentarer? detta ska fungera:

function toggleDropdown(ddName) { var drop = document.getElementsByClassName('dropmenu'); for(i=0; i<drop.length; i++) drop[i].style.display = 'none'; // inte === document.getElementById(ddName).style.display='block'; }

Jag misstänker att du gör fel med for-loopen. Alla "flow control statements"(exempelvis IF och FOR och WHILE), som alltså kontrollerar ingången till en viss kodsnutt måste rutas in med brackets ({ och }) för att visa vad exakt som ingår i If-regeln eller for-loopen. Javascript har dock en liten genväg om man bara har en kod-rad i if-regeln eller for-loopen vilket tillåter att man skippar {}-bracketen, men då gäller bara första kodraden.

for(i=0; i<drop.length; i++) { drop[i].style.display = 'none'; // inte === }

funkar exakt likadant som:

for(i=0; i<drop.length; i++) drop[i].style.display = 'none'; // inte ===

eftersom det bara är en kodrad som ska finnas i for-loopen, men om du vill ha fler rader kod inom for-loopen så måste du använda {}

Trädvy Permalänk
Medlem
Registrerad
Jun 2014
Skrivet av pellle87:

joo så långt tror jag att jag hänger med, såhär ser det ut just nu:

function toggleDropdown(ddName) { var drop = document.getElementsByClassName('dropmenu'); for(i=0; i<drop.length; i++) { drop[i].style.display ='none'; document.getElementById(ddName).style.display='block'; } }

Det där verkar funka för mig? http://codepen.io/anon/pen/dOqgLR

Men du behöver inte ha delen som sätter "display = block" inom for-loopen, den kan du sätta efteråt eftersom det bara ska göras en gång

Trädvy Permalänk
Medlem
Plats
Piteå
Registrerad
Okt 2004
Skrivet av non_noutils:

Det där verkar funka för mig? http://codepen.io/anon/pen/dOqgLR

Men du behöver inte ha delen som sätter "display = block" inom for-loopen, den kan du sätta efteråt eftersom det bara ska göras en gång

Jo det fungerar att öppna, men klickar man igen så stängs den ej som det är tänkt... :/ samt om jag har meny 1 öppen och klickar på meny 2 ska meny 1 stängas... jösses den där förklaringen blev tjorvig.

function toggleDropdown(ddName) { var drop = document.getElementsByClassName('dropmenu'); for(i=0; i<drop.length; i++) { if(drop[i].style.display ='none'){ document.getElementById(ddName).style.display='block'; } else { document.getElementById(ddName).style.display='none'; } }

nu när jag har en meny öppen så stängs den när jag öppnar en annan iaf... men nu är det bara att få till så man kan stänga en meny också. Tänker jag rätt här?!

CPU: AMD Ryzen 1700x @ 3.8GHz || Mem: 16GB Corsair LPX 3000mhz || Mobo: Asus x370 Prime || GPU: EVGA Geforce GTX1070 SC || SSD: WD black 500GB m2 || OS: Linux Mint/Win 10 || Monitor: Dell 43" 4K P4317Q

Citera om du vill ha svar :)

Trädvy Permalänk
Medlem
Registrerad
Jan 2009
Skrivet av pellle87:

Jo det fungerar att öppna, men klickar man igen så stängs den ej som det är tänkt... :/ samt om jag har meny 1 öppen och klickar på meny 2 ska meny 1 stängas... jösses den där förklaringen blev tjorvig.

function toggleDropdown(ddName) { var drop = document.getElementsByClassName('dropmenu'); for(i=0; i<drop.length; i++) { if(drop[i].style.display ='none'){ document.getElementById(ddName).style.display='block'; } else { document.getElementById(ddName).style.display='none'; } }

nu när jag har en meny öppen så stängs den när jag öppnar en annan iaf... men nu är det bara att få till så man kan stänga en meny också. Tänker jag rätt här?!

Den funktionen växlar bara alla fönsters läge?
Fel. Såg att du kör Ddname som id!
Det ska väl fungera?
Förstår inte varför du loopar bara.
Ta bort loopen?

Trädvy Permalänk
Medlem
Registrerad
Jun 2014
Skrivet av Tompanhuhu:

Den funktionen växlar bara alla fönsters läge?
Fel. Såg att du kör Ddname som id!
Det ska väl fungera?
Förstår inte varför du loopar bara.
Ta bort loopen?

Hur skulle han stänga öppna dropdowns då?

Trädvy Permalänk
Medlem
Registrerad
Jun 2014
Skrivet av pellle87:

Jo det fungerar att öppna, men klickar man igen så stängs den ej som det är tänkt... :/ samt om jag har meny 1 öppen och klickar på meny 2 ska meny 1 stängas... jösses den där förklaringen blev tjorvig.

function toggleDropdown(ddName) { var drop = document.getElementsByClassName('dropmenu'); for(i=0; i<drop.length; i++) { if(drop[i].style.display ='none'){ document.getElementById(ddName).style.display='block'; } else { document.getElementById(ddName).style.display='none'; } }

nu när jag har en meny öppen så stängs den när jag öppnar en annan iaf... men nu är det bara att få till så man kan stänga en meny också. Tänker jag rätt här?!

Skrivet av pellle87:

samt om jag har meny 1 öppen och klickar på meny 2 ska meny 1 stängas...

Det gör den för mig så som koden är? Om vi också ska kunna stänga på samma knapp blir det genast lite mer komplicerat. Tänk såhär

1. Vi loopar igenom alla elements
2. Varje element jämförs med den vi klickade på för att se om loopen just nu är på den vi klickade på: if (drop[i].getAttribute('id') == ddName)
2.1 Om den vi klickade på, är den vi just nu loopar över så kan vi där kontrollera om den ska visas eller inte, beroende på det tillstånd den är i just nu
2.2 Om det inte är den vi klickade på, så döljer vi den (för alla utom den vi klickar på ska ju definitivt döljas)

du kan testa lite själv innan du kikar här, om du vill

function toggleDropdown(ddName) { var drop = document.getElementsByClassName('dropmenu'); for(i=0; i<drop.length; i++) { if (drop[i].getAttribute('id') == ddName) { // 2: vi loopade fram till den vi faktiskt klickade på // 2.1: vi kollar om den är synlig just nu, om den är synlig så döljer vi och vice versa if (drop[i].style.display == 'block') { drop[i].style.display = 'none'; } else { drop[i].style.display = 'block'; } } else { // 2.2: vi döljer allt annat drop[i].style.display = 'none'; } } }

Dold text
Trädvy Permalänk
Medlem
Plats
Piteå
Registrerad
Okt 2004
Skrivet av non_noutils:

Det gör den för mig så som koden är? Om vi också ska kunna stänga på samma knapp blir det genast lite mer komplicerat. Tänk såhär

1. Vi loopar igenom alla elements
2. Varje element jämförs med den vi klickade på för att se om loopen just nu är på den vi klickade på: if (drop[i].getAttribute('id') == ddName)
2.1 Om den vi klickade på, är den vi just nu loopar över så kan vi där kontrollera om den ska visas eller inte, beroende på det tillstånd den är i just nu
2.2 Om det inte är den vi klickade på, så döljer vi den (för alla utom den vi klickar på ska ju definitivt döljas)

du kan testa lite själv innan du kikar här, om du vill

function toggleDropdown(ddName) { var drop = document.getElementsByClassName('dropmenu'); for(i=0; i<drop.length; i++) { if (drop[i].getAttribute('id') == ddName) { // 2: vi loopade fram till den vi faktiskt klickade på // 2.1: vi kollar om den är synlig just nu, om den är synlig så döljer vi och vice versa if (drop[i].style.display == 'block') { drop[i].style.display = 'none'; } else { drop[i].style.display = 'block'; } } else { // 2.2: vi döljer allt annat drop[i].style.display = 'none'; } } }

Dold text

Tack för förklaringarna. Jag har inte kollat din kod än, vill försöka ordna detta. Dock har jag slopat idén om att förgående öppna meny ska stängas när jag öppnar en ny, det kändes fel

function toggleDropdown(ddName) { var drop = document.getElementsByClassName('dropmenu'); for(i=0; i<drop.length; i++) { if(ddName.style.display='none'){ document.getElementById(ddName).style.display='block'; } else { drop[i].style.display = 'none'; } } }

är jag nånting på spåret?

CPU: AMD Ryzen 1700x @ 3.8GHz || Mem: 16GB Corsair LPX 3000mhz || Mobo: Asus x370 Prime || GPU: EVGA Geforce GTX1070 SC || SSD: WD black 500GB m2 || OS: Linux Mint/Win 10 || Monitor: Dell 43" 4K P4317Q

Citera om du vill ha svar :)

Trädvy Permalänk
Medlem
Registrerad
Jun 2014
Skrivet av pellle87:

Tack för förklaringarna. Jag har inte kollat din kod än, vill försöka ordna detta. Dock har jag slopat idén om att förgående öppna meny ska stängas när jag öppnar en ny, det kändes fel

function toggleDropdown(ddName) { var drop = document.getElementsByClassName('dropmenu'); for(i=0; i<drop.length; i++) { if(ddName.style.display='none'){ document.getElementById(ddName).style.display='block'; } else { drop[i].style.display = 'none'; } } }

är jag nånting på spåret?

jadå

if(ddName.style.display='none')

missade getElementById() där, samt assignment operatorn (=) istället för en jämförelse operator (== eller ===)

Om du inte vill stänga alla redan öppnade menyer när du klickar en ny meny så behövs inte for-loopen, den har bara en funktion och det är att stänga ALLA dropdowns

Om du tar bort for-loopen och fixar if-regeln så ska det nog funka (kom ihåg att byta ut drop[i]* mot ddName elementet i else-delen)

*eftersom vi inte längre ska loopa igenom alla dropdowns i syfte att stänga dem så behövs inte drop variabeln längre

function toggleDropdown(ddName) { if(document.getElementById(ddName).style.display=='none') { document.getElementById(ddName).style.display='block'; } else { document.getElementById(ddName).style.display = 'none'; } }

Dold text
Trädvy Permalänk
Medlem
Plats
i din garderob
Registrerad
Sep 2007
Skrivet av pellle87:

Jo det fungerar att öppna, men klickar man igen så stängs den ej som det är tänkt... :/ samt om jag har meny 1 öppen och klickar på meny 2 ska meny 1 stängas... jösses den där förklaringen blev tjorvig.

function toggleDropdown(ddName) { var drop = document.getElementsByClassName('dropmenu'); for(i=0; i<drop.length; i++) { if(drop[i].style.display ='none'){ document.getElementById(ddName).style.display='block'; } else { document.getElementById(ddName).style.display='none'; } }

nu när jag har en meny öppen så stängs den när jag öppnar en annan iaf... men nu är det bara att få till så man kan stänga en meny också. Tänker jag rätt här?!

Ännu ett funktionellt exempel, denna gång mer rakt på sak: http://codepen.io/anon/pen/ZBMwVz

De allra flesta rekommenderar iterativa for(var x=0; x<y.length; x++) { blah bleh } loopar vilket jag tycker är synd. Funktionella angreppssätt är subjektivt snyggare och lämnar mindre chans till fel, och uppmuntrar till bättre kod.

I koden jag länkar till är själva huvuduppgiften beskriven i stycket

elems.forEach(function (elem) { elem.addEventListener('click', function () { elems.filter(function (e) { return e !== elem }).forEach(close) toggle(elem) }) })

Detta stycke säger, rad för rad:
1. Gå igenom alla elems (element vi har valt ut);
2. Lägg till en klick-lyssnare som...
3. .. stänger alla element förutom det som just blev klickat på och
4. .. därefter "togglar" det element som klickades.

Funktionerna som sköter stängande (close) och togglande (toggle) är definierade högre upp i koden. Vill du att element inte ska stängas automatiskt är det bara att ta kommentera ut eller ta bort rad #3 så är du klar.

När nästa version av JavaScript — som baseras på Ecmascript 6 — kommer ut på bred front kommer man skriva det stycket ännu mer koncist (och, återigen subjektivt, snyggare) och många av de andra funktionerna också:

elems.forEach( elem => elem.addEventListener('click', () => { elems.filter( e => e !== elem ).forEach(close) toggle(elem) }) )

Det kan se konstigare ut till en början men när det satt sig är det svårt att gå tillbaka.

Bilanaloger är som Volvo — varenda svenne kör med dem

Trädvy Permalänk
Medlem
Plats
Piteå
Registrerad
Okt 2004
Skrivet av non_noutils:

jadå

if(ddName.style.display='none')

missade getElementById() där, samt assignment operatorn (=) istället för en jämförelse operator (== eller ===)

Om du inte vill stänga alla redan öppnade menyer när du klickar en ny meny så behövs inte for-loopen, den har bara en funktion och det är att stänga ALLA dropdowns

Om du tar bort for-loopen och fixar if-regeln så ska det nog funka (kom ihåg att byta ut drop[i]* mot ddName elementet i else-delen)

*eftersom vi inte längre ska loopa igenom alla dropdowns i syfte att stänga dem så behövs inte drop variabeln längre

function toggleDropdown(ddName) { if(document.getElementById(ddName).style.display=='none') { document.getElementById(ddName).style.display='block'; } else { document.getElementById(ddName).style.display = 'none'; } }

Dold text

Tack! nu är det löst iaf. Kul att det finns folk som tar sig tid att förklara

Skrivet av Teknocide:

Ännu ett funktionellt exempel, denna gång mer rakt på sak: http://codepen.io/anon/pen/ZBMwVz

De allra flesta rekommenderar iterativa for(var x=0; x<y.length; x++) { blah bleh } loopar vilket jag tycker är synd. Funktionella angreppssätt är subjektivt snyggare och lämnar mindre chans till fel, och uppmuntrar till bättre kod.

I koden jag länkar till är själva huvuduppgiften beskriven i stycket

elems.forEach(function (elem) { elem.addEventListener('click', function () { elems.filter(function (e) { return e !== elem }).forEach(close) toggle(elem) }) })

Detta stycke säger, rad för rad:
1. Gå igenom alla elems (element vi har valt ut);
2. Lägg till en klick-lyssnare som...
3. .. stänger alla element förutom det som just blev klickat på och
4. .. därefter "togglar" det element som klickades.

Funktionerna som sköter stängande (close) och togglande (toggle) är definierade högre upp i koden. Vill du att element inte ska stängas automatiskt är det bara att ta kommentera ut eller ta bort rad #3 så är du klar.

När nästa version av JavaScript — som baseras på Ecmascript 6 — kommer ut på bred front kommer man skriva det stycket ännu mer koncist (och, återigen subjektivt, snyggare) och många av de andra funktionerna också:

elems.forEach( elem => elem.addEventListener('click', () => { elems.filter( e => e !== elem ).forEach(close) toggle(elem) }) )

Det kan se konstigare ut till en början men när det satt sig är det svårt att gå tillbaka.

Det där verkar ju riktigt intressant men känns lite över min nivå just nu, ska dock ha det i bakskallen

CPU: AMD Ryzen 1700x @ 3.8GHz || Mem: 16GB Corsair LPX 3000mhz || Mobo: Asus x370 Prime || GPU: EVGA Geforce GTX1070 SC || SSD: WD black 500GB m2 || OS: Linux Mint/Win 10 || Monitor: Dell 43" 4K P4317Q

Citera om du vill ha svar :)