web-dev-qa-db-fra.com

Icône de menu mobile Bootstrap changer pour x fermer

J'aimerais que, lorsque vous êtes dans la vue mobile, l'icône du menu (définie avec la classe icon-bar dans l'exemple de base de la barre de navigation bootstrap) passe à une forme en X (quelque chose de similaire à ce qui se passe ici: https://www.mint .com mais moins de fantaisie (je veux juste remplacer les 3 bandes par un X).

En ce moment, j'utilise un identifiant personnalisé: #ChangeToggle

<button id="ChangeToggle" type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
</button>

Avec la fonction javascript suivante (je sais que c'est basique mais je suis novice dans ce domaine):

<script>    
$('#ChangeToggle').click(function () {
    if($('#ChangeToggle span').hasClass('ToggleButton')) {
        $('#ChangeToggle').html('<span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>'); 
    }
    else {      
        $('#ChangeToggle').html('<span class="ToggleButton glyphicon glyphicon-remove"></span>'); 
    }
});
</script>

Tout fonctionne, le seul problème est que lorsque je clique exactement sur l'icône X, le menu ne se ferme pas. Il ne ferme que lorsque je clique en dehors de celui-ci (n'importe où ailleurs dans le bouton). La seule chose qu’il fait en cliquant sur l’icône X revient aux 3 bandes originales.

Quelqu'un sait ce que je fais mal?

5
DoubleD

Votre JavaScript remplace le code HTML interne de l'élément #ChangeToggle pour afficher l'icône X ou l'icône hamburger. En cliquant précisément sur le X ou le menu hamburger au lieu du #ChangeToggle, vous supprimerez l'élément sur lequel vous cliquez, ce qui, à mon avis, l'empêche de bouillonner. Comme le plugin collapse de Bootstrap utilise un gestionnaire d'événements sur le document pour déterminer si un élément a été cliqué, le plugin collapse ne sera jamais notifié.

J'ai créé un petit exemple dans lequel un gestionnaire de clics sur la zone .outer rose remplace la zone .inner verte. Notez que cliquer sur la zone rose (votre #ChangeToggle) entraînera deux événements, le fait de cliquer sur la zone verte (votre icône X) conduisant à un seul événement.

$(function() {
  $('.outer')
    .click(function() {
      $('.outer').html('<div class="inner"></div>');
      fired('.js-outer');
    });

  $(document).on('click', '.outer', function() {
    fired('.js-document');
  });
});

function fired(el) {
  $(el).addClass('event--fire');
  window.setTimeout(function() {
    $(el).removeClass('event--fire')
  }, 100);
}
body {
  font-family: Helvetica Neue, Helvetica, Arial;
}
.outer,
.inner {
  display: inline-block;
  padding: 20px;
}
.outer {
  border: 1px solid #c66;
  background-color: #f99;
}
.inner {
  border: 1px solid #6c6;
  background-color: #9f9;
}
.event {
  margin: 10px 0;
}
.event::before {
  display: inline-block;
  content: '';
  border: 1px solid #ccc;
  padding: 10px;
  vertical-align: middle;
  margin-right: 10px;
}
.event--fire:before {
  background-color: #ff9;
}
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>


<div class="outer">
  <div class="inner">
  </div>
</div>

<div class="event js-outer">Event fires on .outer</div>
<div class="event js-document">Event fires on document</div>

Le moyen le plus simple de résoudre ce problème pour votre barre de navigation consiste à masquer/afficher l'icône en forme de X ou d'hamburger au lieu de la remplacer. Dans l'exemple ci-dessous, l'icône X et l'icône hamburger sont au format HTML, et le basculement de la classe .hidden permet d'afficher l'icône appropriée.

$(function() {
  $('#ChangeToggle').click(function() {
    $('#navbar-hamburger').toggleClass('hidden');
    $('#navbar-close').toggleClass('hidden');  
  });
});
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<nav class="navbar navbar-default">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button id="ChangeToggle" type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <div id="navbar-hamburger">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </div>
        <div id="navbar-close" class="hidden">
          <span class="glyphicon glyphicon-remove"></span>
        </div>
      </button>
      <a class="navbar-brand" href="#">Brand</a>
    </div>

    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a>
        </li>
      </ul>
    </div>
  </div>
</nav>

Au lieu d’ajouter un gestionnaire de clic jQuery à côté du plug-in de réduction de Bootstrap, vous pouvez également utiliser les événements déclenchés par le plug-in de réduction pour masquer ou afficher la bonne icône. Utilisez l'événement shown.bs.collapse pour afficher l'icône X et l'événement hidden.bs.collapse pour afficher l'icône hamburger.

$(function() {
  
  $('#bs-example-navbar-collapse-1')
    .on('shown.bs.collapse', function() {
      $('#navbar-hamburger').addClass('hidden');
      $('#navbar-close').removeClass('hidden');    
    })
    .on('hidden.bs.collapse', function() {
      $('#navbar-hamburger').removeClass('hidden');
      $('#navbar-close').addClass('hidden');        
    });
  
});
#navbar-close {
  color: #888;
  width: 22px;
  height: 14px;
}
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<nav class="navbar navbar-default">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button id="ChangeToggle" type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <div id="navbar-hamburger">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </div>
        <div id="navbar-close" class="hidden">
          <span class="glyphicon glyphicon-remove"></span>
        </div>
      </button>
      <a class="navbar-brand" href="#">Brand</a>
    </div>

    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a>
        </li>
      </ul>
    </div>
  </div>
</nav>

13
ckuijjer

Vous n'avez pas besoin de Javascript, CSS fera le travail

.navbar-toggle {
    .icon-bar {
        transition: 300ms ease-in-out;
        background-color: #fff;
        position: relative;
        width: 24px;
        height: 3px;
    }
    .icon-bar:last-child {
        -webkit-transform: rotate(-45deg);
        -ms-transform: rotate(-45deg);
        -o-transform: rotate(-45deg);
        transform: rotate(-45deg);
        top: -7px;
    }
    .icon-bar:nth-child(2) {
        -webkit-transform: rotate(45deg);
        -ms-transform: rotate(45deg);
        -o-transform: rotate(45deg);
        transform: rotate(45deg);
        top: 0px;
    }
    .icon-bar:nth-child(3) {
        opacity: 0;
    }
    &.collapsed {
        .icon-bar {
            -webkit-transform: rotate(0deg);
            -ms-transform: rotate(0deg);
            -o-transform: rotate(0deg);
            transform: rotate(0deg);        
            top: 0;
            opacity: 1;
        }
    }
}
9
Helmut

Smart décision m'a aidé dans codepen

HTML

<div class="navbar-header">
     <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
         <span class="icon-bar"></span>
         <span class="icon-bar"></span>
         <span class="icon-bar"></span>
     </button>
</div>

CSS

.navbar-toggle .icon-bar:nth-of-type(2) {
    top: 1px;
}
.navbar-toggle .icon-bar {
    position: relative;
    transition: all 500ms ease-in-out;
}
.navbar-toggle.active .icon-bar:nth-of-type(1) {
    top: 6px;
    transform: rotate(45deg);
}
.navbar-toggle.active .icon-bar:nth-of-type(2) {
    background-color: transparent;
}
.navbar-toggle.active .icon-bar:nth-of-type(3) {
    top: -6px;
    transform: rotate(-45deg);
}

JS

$(".navbar-toggle").on("click", function () {
    $(this).toggleClass("active");
});
3
dimitar

Le code ci-dessous vous aide à résoudre ce problème.

Html:

<div class="content">
<h1>Mobile Navigation menu using css and jquery</h1>
<div class="icons">
<button class="icon">
<span></span>
<span></span>
<span></span>
</button>
</div>
</div>

css:

.btn {
background-color: #ffd200;
color: #00174f;
display: inline-block;
text-decoration: none;
padding: 13px 30px;
margin: 30px 0 0 0;
border-radius: 3px;
font-weight: bold;
}
.btn:hover {
background-color: #fff;
}
.btn--transition {
-webkit-transition: -webkit-transform 0.2s;
-webkit-transition: all 200ms ease-in-out;
transition: all 200ms ease-in-out;
}
:focus {
outline: none;
}
.icons {
margin: 50px 0;
}
.icon {
margin: 0 30px 0 0;
}

.icon {
background-color: #ff3000;
border: 0;
height: 79px;
width: 79px;
border-radius: 50%;
cursor: pointer;
position: relative;
}
.icon span {
display: block;
height: 5px;
width: 33px;
background-color: #ffffff;
border-radius: 2px;
position: absolute;
left: 23px;
-webkit-transition: -webkit-transform 0.3s;
-webkit-transition: all 300ms ease-in-out;
transition: all 300ms ease-in-out;
}
.icon span:first-child {
top: 28px;
}
.icon span:nth-child(2) {
top: 37px;
}
.icon span:last-child {
top: 46px;
}
.icon--active span:first-child {
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
position: absolute;
top: 37px;
}
.icon--active span:last-child {
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
position: absolute;
top: 37px;
}
.icon--active span:nth-child(2) {
opacity: 0;
}
.icon--button {
border-radius: 10px;
}
.icon-transition {
-webkit-transition: -webkit-transform 0.3s;
-webkit-transition: all 300ms ease-in-out;
transition: all 300ms ease-in-out;
}

javascript

<script>
var animation = 'rubberBand';
$('.icon').on('click', function () {
$(this).toggleClass('icon--active');
});
$('.icon').on('click', function () {
$(this).addClass('animated ' + animation).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
$(this).removeClass('animated ' + animation);
});
});
</script>

Ce bout de code est utilisé pour changer l'icône du mobile afin de fermer l'icône en cliquant sur le bouton. Demo

0
M. Lak