Bonjour à tous,
Je me prends le chou depuis plusieurs jours à faire en sorte que les li de mon menu se placent dans un dropdown menu, selon la largeur de son
conteneur.
Ma page fonctionne aussi avec bootsrap.
Voici mon menu (Je mets la partie concernée plus bas avec des commentaires sur mon raisonnement)
Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 <div class="container-fluid"> <div class="row bg-firstrow"> <div class="col-sm-2 hidden-sm hidden-xs"> <ul class="nav navbar-nav navbar-nav-left-width"> <li class="frame-left"> </li> <li class="active"> <a href="#">f</a> </li> <li> <a href="#">t</a> </li> <li class="frame-left"> </li> </ul> </div> <div class="col-sm-10" style="border:1px solid #ff2222"> <a class="navbar-brand" href="#" style="border:1px solid #ff22ff"> <img alt="Lacustre" t itle="Restaurant lacustre Genève" src="images/logo-lacustre.jpg"> </a> <nav class="navbar-default" role="navigation"> <!--<nav class="navbar navbar-default navbar-toggleable-md" role="navigation"> --> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav menu" style="border:1px solid yellow"> <li id="0" class="item active"> <a href="#">Accueil</a> <span></span> </li> <li id="1" class="item"> <a href="#">Carte et menu</a> <span></span> </li> <li id="2" class="item"> <a href="#">Evénements</a> <span></span> </li> <li id="3" class="item"> <a href="#">La Yourte</a> <span></span> </li> <li id="4" class="item"> <a href="#">La Buevette</a> <span></span> </li> <li id="5" class="item"> <a href="#">Galerie</a> <span></span> </li> <li id="6" class="item"> <a href="#">Contact</a> <span></span> </li> <li class="dropdown item more"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">More<strong class="caret"></strong></a> <span></span> <ul class="dropdown-menu"> <li> <a href="#">FR</a> </li> <li> <a href="#">EN</a> </li> </ul> </li> </ul> </nav> </div> <!-- End col --> </div> </div>
et voici la partie concernée
Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 <!-- Conteneur --> <div class="col-sm-10" style="border:1px solid #ff2222"> <!-- Logo --> <a class="navbar-brand" href="#" style="border:1px solid #ff22ff"> <img alt="Lacustre" t itle="Restaurant lacustre Genève" src="images/logo-lacustre.jpg"> </a> <nav class="navbar-default" role="navigation"> <!--<nav class="navbar navbar-default navbar-toggleable-md" role="navigation"> --> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <!-- menu --> <ul class="nav navbar-nav menu" style="border:1px solid yellow"> <li id="0" class="item active"> <a href="#">Accueil</a> <span></span> </li> <li id="1" class="item"> <a href="#">Carte et menu</a> <span></span> </li> <li id="2" class="item"> <a href="#">Evénements</a> <span></span> </li> <li id="3" class="item"> <a href="#">La Yourte</a> <span></span> </li> <li id="4" class="item"> <a href="#">La Buevette</a> <span></span> </li> <li id="5" class="item"> <a href="#">Galerie</a> <span></span> </li> <li id="6" class="item"> <a href="#">Contact</a> <span></span> </li> <li class="dropdown item more"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">More<strong class="caret"></strong></a> <span></span> <ul class="dropdown-menu"> <li> <a href="#">FR</a> </li> <li> <a href="#">EN</a> </li> </ul> </li> </ul> </nav> </div> <!-- End col -->
Quand le browser, prend tout l'écran, on voit tous les li, du id="1" jusqu'au menu déroulant .more
A savoir que mon menu réroulant (.more) doit toujours rester visible
Quand je diminue le browser et que le conteneur arrive en butée contre le ul.menu, le dernier li, soit id="6", est déplacé dans le menu déroulant qui a
la class
.more .dropdown-menu.
Et plus je le diminue, plus il ajoutera de li dans le menu déroulant, de l'id le plus grand plus petit (en gardant le meme ordre) .
Dans le sens inverse aussi, plus j'agrandi mon navigateur et que le ul.menu s'aggrandi, il replacera le premier li qui se trouve dans le menu déroulant après son prédécesseur (id="4" après l 'id="3").
Je crois que mon problème est de bien calculer, en tenant compte des margin et padding ajouté par bootstrap.
Evidemment, quand je charge ou recharge la page, les li doivent se placer correctement en fonction de la largeur du conteneu (<div class="col-md-10">)
Connaitriez-vous un script existant me permettant de faire ceci?
Pourriez-vous m'aider à corriger mon code?
Voci comment je le fait.
D'abord, dans mon fichier script.js, j'ai ceci
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 $(window).on('resize', function() { menuWidth(0); }); $(window).on('load', function() { addID(); menuWidth(1); });
addID, va m'ajouter dynamiquement les id au li. Ca marche et je passe ceci. Est-ce qu'on peut faire sans?
Maintenant, je passe sur tous mes li, avec each().
Je commente mon code
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 var containerWidth = 0; var containerWidthPrev = 0; var browserWidthPrev =0; var browserWidth =0; function menuWidth(onLoad){ var widthItemMenuTotal = 0; // Ici je controlle si le navigateur est agrandi ou raptici browserWidthPrev = browserWidth; // save the previous browser width browserWidth = $(window).width(); //$('.ws').text(containerWidth2 - brandWidth2 -60); if(browserWidthPrev == browserWidth || browserWidthPrev == 0){ windowIncrease = 0 // Do nothing }else if(browserWidthPrev > browserWidth){ console.info("DECREASE"); windowIncrease = -1; }else if(browserWidthPrev < browserWidth){ console.info("INCREASE"); windowIncrease = 1; } /* * Loop at each Li element */ $('ul.menu li.item').each(function() { // Calcul la largeur d'un li et je l'additionne dans withItemMenuTotal pour avoir la largeur au fur et à mesure widthItem = $(this).outerWidth(); widthItemMenuTotal += widthItem; // Je calcul la largeur du logo, puisqu'il occupe de la place avant le menu, et dans le conteneur brandWidth = $(".bg-firstrow .col-sm-10 .navbar-brand").outerWidth() // Je clacul la largeur du conteneur, dont je déduit la largeur du logo. J'enlève arbitrairement 20. containerWidth = $(".bg-firstrow .col-sm-10").outerWidth() - brandWidth - 20; Ensuite, je compare cette valeur avec la largeur du menu, soit ul.menu // Je relève l'id du li en cours var idLi = parseInt($(this).attr('id')); //Je relève l'id de son prédécesseur var prevIdLi = idLi-1; // Si je charge ou recharge ma page /* * Onload */ if(onLoad == 1){ // Je parcours mes li, et si la largeur des li, à ce moment est plus grande que son conteur // Je mets le reste des li, dans le menu déroulant "more" if(widthItemMenuTotal > containerWidth){ // J'ajoute un divider if( $(".more .dropdown-menu").find("li.item").length == 0){ $(".more .dropdown-menu").prepend('<li class="divider"></li>'); // Je boucle les derniers li, et je les déplace dans le menu déroulant .more for(i=prevIdLi; i <= totalItem; i++){ $("#" + i).insertBefore( ".more .dropdown-menu .divider" ); } // Je sors de mon menu return false; } } // Si je ne recharge pas ma page, mais je change la largeur de mon navigateur }else if(onLoad == 0){ // Si je diminue la largeur de mon browser et que le container est plsu petit que la largeur de mon menu if(windowIncrease < 1 && widthItemMenuTotal > containerWidth ){ // Et si le li qui va etre déplacé est bien enfant à ul.menu, déplace le if($("#" + idLi).parent(".menu")){ // Check if the is li.item and add a divider if( $(".more .dropdown-menu").find("li.item").length == 0){ // Si c'est le premier li avec la class.item, ajoute un divider $(".more .dropdown-menu").prepend('<li class="divider"></li>'); // Ajoute avant le divider $("#" + prevIdLi).insertBefore( ".more .dropdown-menu .divider" ); }else{ // Si non, ajoute le avant son successeur, de maniere a garder le meme ordre dans le menu déroulant $("#" + prevIdLi).insertBefore( ".more .dropdown-menu li#" + idLi ); } }else{ console.error("Parent is not .menu"); } } // JUSQU'A LA; CA SEMBLE FONCTIONNE, MAIS JE PENSE DE TOUTE MANIERE, QUE JE NE CALCULER PAS BIEN LA LARGEUR DES DIV. // JE NE SAIS PAS SI JE TIENS BIEN EN COMPTE LE PADDING ET MARGIN // Maintenant, je dois faire l'inverse. Et la je penine énormément. // AU fure et à mesure que j'agrandi mon navigateur, je dois controller si il y a de la place, pour remettre le premier // li, qui se trouve dans le menu déroulant, dans le menu horizontal, soit juste après son prédécesseur. // L'id="4", se place donc après l'id="3", toujours pour garder le meme ordre }else if(windowIncrease == 1){ // Increasing the browser width // Je récupère l'id suivant de celui qu'on parcour nextIdLi = idLi; nextIdLi = nextIdLi+1; // Si à ce moement, la largeur du menu + la largeur du premier li du menu déroulant est // plus grans que la largeur du conteneur, alors replace le if( (widthItemMenuTotal + $("li#" + nextIdLi + " a").width()) > containerWidth) { // Controlle s'il est bien enfant au menu déroulant if($("#" + nextIdLi).parent(".more .dropdown-menu") ){ // Replace le après son rpédécesseur $("#" + nextIdLi).insertAfter( $(this).parent().find('li#' + idLi) ); }else{ console.info("Parent is not .more"); } } } } }
Ca semble fonctionner quand je rapetissi le navigateur, mais quand je l'agrandi, ca part un peu en cacahuète.
Je ne suis pas convaincu de le faire correctement.
Mais ce je ne suis encore moins convaincu, c'est de bien calculer la largeur des conteneurs du menu (ul.menu) et le conteneur (.col-md-10), en fonction de padding et margin ajoutés par
bootstrap et j'aimerais bien qu'il fasse tout ca dynamiquement, en tenant aussi en compte la largeur du logo, vu qu'il est en float.
Pourriez-vous m'aider a faire ce que je cherche à faire?
M'aider à faire plus simple et plus propre et mieux?
je vous remercie pleinement
Partager