Content toevoegen aan menu-item
Ik wil graag een + toevoegen aan elk menu-item waaronder een submenu hangt. Om submenu open of dicht te kunnen klappen.
Dit is globaal de opbouw vh menu:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<ul id="mobile-nav">
<li>Item 1</li>
<li class="menu-item-has-children">Item 2</li>
<ul>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ul>
<li>Item 3</li>
</ul>
<li>Item 1</li>
<li class="menu-item-has-children">Item 2</li>
<ul>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ul>
<li>Item 3</li>
</ul>
Ik heb deze JS die in de head geladen wordt, maar er gebeurt niets:
Code (php)
1
2
3
2
3
var x = document.createElement("button");
x.setAttribute("name", " + ");
document.getElementById("mobile-nav").getElementsByClassName("menu-item-has-children").appendChild(x);
x.setAttribute("name", " + ");
document.getElementById("mobile-nav").getElementsByClassName("menu-item-has-children").appendChild(x);
Wat doe ik verkeerd?
Guido
Gewijzigd op 16/04/2021 17:59:56 door Guido -
Het makkelijkst is om je JS-code gewoon helemaal onderaan te hangen (net voor de </body> tag). als dat niet gaat (je de JS dus alleen in de head toe kunt voegen), dan de volgende event listener er "omheen":De "hocus pocus" wordt dan pas uitgevoerd als het document (en dus ook het menu) helemaal is geladen.
Dank, goed punt.
Het werkt overigens nog niet, als ik "mijn" JS binnen deze functie zet zou het uitgevoerd moeten worden, lijkt me? Of is mijn JS niet juist?
Guido
Gewijzigd op 16/04/2021 21:25:06 door Guido -
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE html>
<html>
<head>
<script>
window.addEventListener('DOMContentLoaded', function() {
let button = document.createElement('button');
button.innerHTML = '+';
button.addEventListener('click', function() {
let ul = this.parentNode.getElementsByTagName('ul')[0];
ul.style.display = (ul.style.display == '') ? 'none' : '';
});
let list = document.getElementById('mobile-nav')
.getElementsByClassName('menu-item-has-children');
for (let index = 0; index < list.length; index++) {
let li = list[index];
let ul = li.parentNode.getElementsByTagName('ul')[0];
li.insertBefore(button, ul);
}
});
</script>
</head>
<body>
<ul id="mobile-nav">
<li>Item 1</li>
<li class="menu-item-has-children">Item 2
<ul>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ul>
</li>
<li>Item 3</li>
</ul>
</body>
</html>
<html>
<head>
<script>
window.addEventListener('DOMContentLoaded', function() {
let button = document.createElement('button');
button.innerHTML = '+';
button.addEventListener('click', function() {
let ul = this.parentNode.getElementsByTagName('ul')[0];
ul.style.display = (ul.style.display == '') ? 'none' : '';
});
let list = document.getElementById('mobile-nav')
.getElementsByClassName('menu-item-has-children');
for (let index = 0; index < list.length; index++) {
let li = list[index];
let ul = li.parentNode.getElementsByTagName('ul')[0];
li.insertBefore(button, ul);
}
});
</script>
</head>
<body>
<ul id="mobile-nav">
<li>Item 1</li>
<li class="menu-item-has-children">Item 2
<ul>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ul>
</li>
<li>Item 3</li>
</ul>
</body>
</html>
Bedankt voor dit werkende voorbeeld, ik had niet verwacht dat er nog zo veel extra code benodigd is om dit voor elkaar te krijgen.
Guido
Iemand die daar al jarenlang mee bezig is, heeft allerlei voorbeelden op z'n site die je zo kan overnemen.
Zie http://www.cssplay.co.uk/menus
Ik merk nu wel dat de "toggle" alleen wordt toegevoegd aan 1 item met subpagina's.
Guido
Toevoeging op 17/04/2021 11:08:01:
Ad Fundum op 17/04/2021 10:59:58:
Als je liever geen gebruik maakt van JavaScript, dan kan je ook menu's maken met alleen HTML en CSS.
Dank, ga ik ook even naar kijken.. CSS is meer mijn ding ;-)
Ik heb na veel werk en met het voorbeeld hierboven een werkend script gemaakt:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<script>
// Verberg submenu
window.addEventListener('DOMContentLoaded', function() {
var div = document.getElementById("mobile-nav");
var sub = div.getElementsByClassName("sub-menu");
for (let i = 0; i < sub.length; ++i) {
sub[i].style.display = "none";
}
});
// Voeg klik button toe en toon submenu
window.addEventListener('DOMContentLoaded', function() {
var x = document.getElementById("mobile-nav").querySelectorAll('.menu-item-has-children > a');
for( let index = 0; index < x.length; index++ ) {
var button = document.createElement('button'); button.className = 'subnav-toggle'; button.innerHTML = '+';
x[index].parentNode.insertBefore(button, x[index].nextSibling);
button.addEventListener('click', function() {
var ul = this.parentNode.getElementsByTagName('ul')[0];
ul.style.display = (ul.style.display == 'block') ? 'none' : 'block';
});
};
});
</script>
<div id="mobile-nav">
<ul>
<li>Item 1</li>
<li class="menu-item-has-children"><a>Item 2</a>
<ul class="sub-menu">
<li><a>Subitem 1</a></li>
<li><a>Subitem 2</a></li>
</ul>
</li>
<li><a>Item 3</a></li>
<li class="menu-item-has-children"><a>Item 4</a>
<ul class="sub-menu">
<li><a>Subitem 3</a></li>
<li><a>Subitem 4</a></li>
</ul>
</li>
</ul>
</div>
// Verberg submenu
window.addEventListener('DOMContentLoaded', function() {
var div = document.getElementById("mobile-nav");
var sub = div.getElementsByClassName("sub-menu");
for (let i = 0; i < sub.length; ++i) {
sub[i].style.display = "none";
}
});
// Voeg klik button toe en toon submenu
window.addEventListener('DOMContentLoaded', function() {
var x = document.getElementById("mobile-nav").querySelectorAll('.menu-item-has-children > a');
for( let index = 0; index < x.length; index++ ) {
var button = document.createElement('button'); button.className = 'subnav-toggle'; button.innerHTML = '+';
x[index].parentNode.insertBefore(button, x[index].nextSibling);
button.addEventListener('click', function() {
var ul = this.parentNode.getElementsByTagName('ul')[0];
ul.style.display = (ul.style.display == 'block') ? 'none' : 'block';
});
};
});
</script>
<div id="mobile-nav">
<ul>
<li>Item 1</li>
<li class="menu-item-has-children"><a>Item 2</a>
<ul class="sub-menu">
<li><a>Subitem 1</a></li>
<li><a>Subitem 2</a></li>
</ul>
</li>
<li><a>Item 3</a></li>
<li class="menu-item-has-children"><a>Item 4</a>
<ul class="sub-menu">
<li><a>Subitem 3</a></li>
<li><a>Subitem 4</a></li>
</ul>
</li>
</ul>
</div>
Zou je die eens kunnen nakijken op fouten en verbeteringen, want ben nog een echte leek ;-)
Guido
Gewijzigd op 19/04/2021 21:32:23 door Guido -
Er zijn een paar dingetjes:
- JavaScript kan met CSS werken, en die eerste functie kan in 1 regel CSS
- Verder gebruik ik bij voorkeur let boven var, vanwege de variabele scope
- Als laatste zou ik de namen van variabelen zinvolle namen geven, dus liever "list" in plaats van "x"
Code (php)
1
2
3
2
3
<style>
.menu-item-has-children > .sub-menu {display: none;} /* Verberg submenu */
</style>
.menu-item-has-children > .sub-menu {display: none;} /* Verberg submenu */
</style>
Bedankt voor je reactie.
1) Ik weet dat ik het kan verbergen met CSS (ga ik ook doen, als fall-back), maar ik wou alles ook via JS regelen. Of is dat geen best-practice?
2) Ik begreep dat let alleen binnen de betreffende loop werkt. In mijn 2 functies wordt de var/let niet opnieuw aangeroepen buiten de loop, dus betekent dit dat ik alle var door let kan vervangen?
Guido