web-dev-qa-db-ja.com

Bootstrapモバイルメニューアイコンをxに変更

[〜#〜]編集[〜#〜]

@ zim 回答は2020 CSSを使用して問題を簡単に解決し、Bootstrap 4。

元の質問と選択した回答はまだ有効であり、非常に有益です。

元の質問

モバイルビューで、メニューアイコン(bootstrap基本的なナビゲーションバーの例でクラスicon-barを使用して定義)をX形状に変更します(ここで発生するようなもの: https://www.mint.com しかし、それほど豪華ではありません(3つのストライプをXに置き換えたいだけです)。

現時点では、カスタムID #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>

次のjavascript関数に加えて(基本的なものであることはわかっていますが、これは初めてです):

<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>

すべてが機能し、唯一の問題は、Xアイコンを正確にクリックしてもメニューが閉じないことです。それの外側(ボタンの他​​の場所)をクリックしたときにのみ閉じます。 Xアイコンをクリックしている間は、元の3つのストライプに戻るだけです。

誰かが私が間違っていることを知っていますか?

9
DoubleD

JavaScriptは#ChangeToggle要素の内部のhtmlを置き換えて、Xまたはハンバーガーアイコンを表示します。 #ChangeToggleの代わりにXまたはハンバーガーメニューを正確にクリックすると、クリックされている要素が削除され、泡が発生しなくなると思います。 Bootstrapの 折りたたみプラグイン はドキュメントのイベントハンドラーを使用して要素がクリックされたかどうかを判断するため、折りたたみプラグインは通知されません。

ピンク色の.outer領域のクリックハンドラーが緑色の.inner領域に置き換わる小さな例を作成しました。ピンク色の領域(#ChangeToggle)をクリックすると2つのイベントが発生し、緑色の領域(Xアイコン)をクリックすると1つのイベントが発生することに注意してください。

$(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>

ナビゲーションバーのこの問題を解決する最も簡単な方法は、Xアイコンまたはハンバーガーアイコンを置き換えるのではなく、表示/非表示にすることです。以下の例では、Xとハンバーガーアイコンの両方がhtmlにあり、クラス.hiddenを切り替えると、正しいアイコンが表示されます。

$(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>

Bootstrapの折りたたみプラグインの横にjQueryクリックハンドラーを追加する代わりに、 折りたたみプラグインによって発生したイベント を使用して正しいアイコンを表示または非表示にすることもできます。 shown.bs.collapseイベントを使用してXアイコンを表示し、hidden.bs.collapseイベントを使用してハンバーガーアイコンを表示します。

$(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>
16
ckuijjer

JavaScriptは必要ありません。CSSがその仕事をします

.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;
        }
    }
}
11
Helmut

賢い決定がコードペンで私を助けました

[〜#〜] 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");
});
4
dimitar

以下のコードは、この問題を解決するのに役立ちます。

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>

このスニペットは、ボタンをクリックしたときにモバイルアイコンを閉じるアイコンに変更するために使用されます。 Demo

1
M. Lak

CSSを介してJavaScriptを使用する必要はありません。以下のコードに従ってください。

[〜#〜] 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 [〜#〜](CSSでは:notこれは、JavaScriptではなく高速アニメーションを実行します)

.navbar-toggle .icon-bar {
    position: relative;
    transition: all 200ms ease-in-out;
}

.navbar-toggle:not(.collapsed) .icon-bar:nth-of-type(1) {
    top: 6px;
    transform: rotate(45deg);
}

.navbar-toggle:not(.collapsed) .icon-bar:nth-of-type(2) {
    background-color: transparent;
}

.navbar-toggle:not(.collapsed) .icon-bar:nth-of-type(3) {
    top: -6px;
    transform: rotate(-45deg);
}      
1
Soubhagya Kumar

@Zimのソリューションを試しましたが、共有してくれてありがとうございます。 2つの微調整を行いました。

  1. ハンバーガーのイメージの周囲にボーダーを維持するために、border-0をborder-1に変更しました。
  2. Xが既存の背景と同じ色になったため、divに背景色を追加しました。
0