IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

jQuery Discussion :

Adapter mon menu en fonction de la largeur de son conteneur


Sujet :

jQuery

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 167
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 167
    Par défaut Adapter mon menu en fonction de la largeur de son conteneur
    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">
    								&nbsp;
    							</li>
    							<li class="active">
    								<a href="#">f</a>
    							</li>
     
    							<li>
    								<a href="#">t</a>
    							</li>
     
     
    							<li class="frame-left">
    								&nbsp;
    							</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

  2. #2
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 694
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 694
    Par défaut
    je me demande si cela sera clair pour le visiteur s'il se trouve avec une partie du menu affichée en ligne et la fin dans un menu déroulant
    si le menu est trop grand, je m'attendrai plutot à retrouver tous les éléments ensemble dans le menu déroulant et cela est faisable avec un peu de CSS

Discussions similaires

  1. Comment ouvrir mon menu deroulant vers la droite ?
    Par enrico83600 dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 19/11/2009, 00h09
  2. comment modifier mon menu deroulant
    Par gaya102 dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 19/03/2009, 12h31
  3. comment aligner mon menu : images les unes a coté des autres
    Par gaya102 dans le forum Mise en page CSS
    Réponses: 19
    Dernier message: 09/03/2009, 12h42
  4. Comment maîtriser mon menu css correctement ?
    Par Velkan.nexus dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 01/12/2007, 20h32
  5. comment caler mon menu dans image de fond
    Par criscaro dans le forum Mise en page CSS
    Réponses: 12
    Dernier message: 04/12/2006, 11h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo