最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Rotate Bootstrap dropdown caret on toggle and prevent close if clicked inside - Stack Overflow

programmeradmin2浏览0评论

I have the following snippet that rotates .caret on a dropdown-toggle click. This rotates the .caret without issue, however it also rotates all of the other .caret on the page. Will I need to write a click function for every individual .caret and .dropdown-toggle on the page or can I have one that works independently?

Also, is there a way in which I can stop the dropdown-menu closing when and item within it has been clicked?

$(document).ready(function() {
  $(".dropdown-toggle").click(function() {
    $(".caret").toggleClass('rotate-180');
  });
});
ul {
  list-style: none;
}

.caret {
  -moz-transition: transform 1s;
  -webkit-transition: transform 1s;
  transition: transform 1s;
}

.rotate-180 {
  transform: rotate(-180deg);
}
<head>
  <script src=".2.1/jquery.min.js"></script>
  <script src=".3.7/js/bootstrap.min.js"></script>
  <link rel="stylesheet" type="text/css" href="index.css">
  <link rel="stylesheet" type="text/css" href=".3.7/css/bootstrap.min.css">
</head>

<body>
  <ul>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
  </ul>
</body>

I have the following snippet that rotates .caret on a dropdown-toggle click. This rotates the .caret without issue, however it also rotates all of the other .caret on the page. Will I need to write a click function for every individual .caret and .dropdown-toggle on the page or can I have one that works independently?

Also, is there a way in which I can stop the dropdown-menu closing when and item within it has been clicked?

$(document).ready(function() {
  $(".dropdown-toggle").click(function() {
    $(".caret").toggleClass('rotate-180');
  });
});
ul {
  list-style: none;
}

.caret {
  -moz-transition: transform 1s;
  -webkit-transition: transform 1s;
  transition: transform 1s;
}

.rotate-180 {
  transform: rotate(-180deg);
}
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <link rel="stylesheet" type="text/css" href="index.css">
  <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>

<body>
  <ul>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
  </ul>
</body>

Share Improve this question edited Sep 5, 2018 at 18:55 Muhammad Omer Aslam 23.7k9 gold badges46 silver badges69 bronze badges asked Nov 8, 2017 at 9:20 CBreezeCBreeze 2,9657 gold badges43 silver badges101 bronze badges 2
  • "is there a way in which I can stop the dropdown-menu closing when and item within it has been clicked?" If user clicks on a element you want dropdown to remain open? – sol Commented Nov 8, 2017 at 9:27
  • @ovokuro that's correct thanks – CBreeze Commented Nov 8, 2017 at 9:30
Add a comment  | 

5 Answers 5

Reset to default 11

in bootstrap +v4 just add style:

.dropdown-toggle[aria-expanded="true"]:after {
transform: rotate(180deg); 
}
/*for animation*/ 
.dropdown-toggle:after { 
transition: 0.7s; 
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
  </head>
  <body>



            <li class="nav-item dropdown" >
                <a class="nav-link dropdown-toggle" href="#" id="navbarDropdowns" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    Dropdown
                </a>
                <div class="dropdown-menu" aria-labelledby="navbarDropdowns">
                    <a class="dropdown-item" href="#">Action</a>
                    <a class="dropdown-item" href="#">Another action</a>
                    <div class="dropdown-divider"></div>
                    <a class="dropdown-item" href="#">Something else here</a>
                </div>
          </li>



    <!-- jQuery first, then Tether, then Bootstrap JS. -->
    <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
  </body>
</html><!-- roiket -->

See below it works

Edit:

I updated my answer to a more better approach to cover all scenarios, and for the last thing you have asked in your OP about preventing the menu to close, can be done in 2 ways

  1. Bind click event to the dropdown and prevent propagation if it is already open.

  2. You have to remove the data-toggle="dropdown" attribute and implement open and closing of the menu yourself. But I think that would require more lines of code than the one used in the code snippet.

$(document).ready(function() {

  $('.dropdown').on('hidden.bs.dropdown', function(e) {
    $(this).find('.caret').toggleClass('rotate-180');
  });

  $('.dropdown').on('shown.bs.dropdown', function(e) {
    $(this).find('.caret').toggleClass('rotate-180');
  });

  //this is to avoid the menu from closing if clicked inside the menu 
  $('body').on("click", ".dropdown-menu", function(e) {
    $(this).parent().is(".open") && e.stopPropagation();
  });
});
ul {
  list-style: none;
}

.caret {
  -moz-transition: transform 1s;
  -webkit-transition: transform 1s;
  transition: transform 1s;
}

.rotate-180 {
  transform: rotate(-180deg);
}
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <link rel="stylesheet" type="text/css" href="index.css">
  <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>

<body>
  <ul>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
  </ul>
</body>

In bootstrap 3 whenever you click on the dropdown list when it's opening, class="open" appears so I tried this code and it worked just fine!

.open>a>.caret{
  transform: rotate(180deg);
  transition: all ease-out 0.4s;
 }

Try this

    $(document).ready(function () { 
   $( ".dropdown-toggle" ).click( function() {
       $(this).children(".caret").toggleClass('rotate-180');
     });
    $( ".dropdown-menu" ).click( function() {
       $(this).siblings().children(".caret").toggleClass('rotate-180');
     });
   $(document).click(function(e){
      if(!e.target.closest("ul") && $(".caret").hasClass("rotate-180")){
         $(".caret").removeClass('rotate-180');
      }
    })
 });

$(document).ready(function () { 
   $( ".dropdown-toggle" ).click( function() {
	   $(this).children(".caret").toggleClass('rotate-180');
	 });
    $( ".dropdown-menu" ).click( function() {
	   $(this).siblings().children(".caret").toggleClass('rotate-180');
	 });
   $(document).click(function(e){
      if(!e.target.closest("ul") && $(".caret").hasClass("rotate-180")){
         $(".caret").removeClass('rotate-180');
      }
    })
 });
ul {
  list-style: none;
}

.caret {
  -moz-transition: transform 1s;
  -webkit-transition: transform 1s;
  transition: transform 1s;
}

.rotate-180 {
  transform: rotate(-180deg);
}
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <link rel="stylesheet" type="text/css" href="index.css">
  <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
  <ul>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
  </ul>
</body>

Try this.

$(document).ready(function () {
    $( ".dropdown-toggle" ).click( function(){   
      $(this).children(".caret").toggleClass('rotate-180');     
    });  
});
$(document).on("click", function(event){
  var $trigger = $(".caret");
  if($trigger !== event.target && !$trigger.has(event.target).length){
     $(".caret").removeClass('rotate-180');  
  }            
});
ul {
  list-style: none;
}

.caret {
  -moz-transition: transform 1s;
  -webkit-transition: transform 1s;
  transition: transform 1s;
}

.rotate-180 {
  transform: rotate(-180deg);
}
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <link rel="stylesheet" type="text/css" href="index.css">
  <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
  <ul>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Directories <span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a></li>
      </ul>
    </li>
  </ul>
</body>

发布评论

评论列表(0)

  1. 暂无评论