Reputation: 1008
I'm building a dropdown menu and need to add the following functionality to it:
When one dropdown is open and you open another one the previous one needs to close completely before the new one starts to open no matter how fast or slow the dropdown speed is set to.
JQuery
$(document).ready(function() {
$(".click").on("click", function(evt) {
evt.stopPropagation();
var th = $(this);
if (th.hasClass("active")) {
th.removeClass("active");
th.parent().find(".showup").slideUp(900);
$(".main-container").removeClass("black-bg");
}else{
$(".active").removeClass("active");
$(".showup").slideUp(900);
$(".main-container").removeClass("black-bg");
setTimeout(function(){
th.addClass("active");
th.parent().find(".showup").slideDown(900);
$(".main-container").addClass("black-bg");
},250);
}
});
$(".showup").on("click", function(evt) {
evt.stopPropagation();
});
});
$(document).on("click", function() {
$(".active").parent().find(".showup").slideUp(900);
$(".active").toggleClass("active");
if ($(".main-container").hasClass("black-bg")) {
$(".main-container").toggleClass("black-bg");
}
});
Thank you for your help.
Upvotes: 0
Views: 62
Reputation: 23738
You need to use .stop(clearQueue,jumpToEnd)
along with the second parameter for the slideUp()
and slideDown()
i.e complete
callback function to call once the animation is complete, called once per matched element.
you should first hide all open and then call the slideDown
inside the complete callback of the slideUp
so that once the opened menu is completely closed then the new drop-down should be opened.
Notice the 2 parameters passed to the stop()
so that when you click simultaneously the animation should not keep on playing instead skips to the last state either shown or hidden
See a demo below.
$(document).ready(function() {
$(".click").on("click", function(e) {
var menu = $(this);
toggleDropDown(menu);
});
$(document).on('mouseup',function(e) {
var container = $("nav");
// if the target of the click isn't the container nor a descendant of the container
if (!container.is(e.target) && container.has(e.target).length === 0) {
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
$(".main-container").removeClass("black-bg");
if ($('a.active').hasClass('active')) {
$('a.active').removeClass('active');
}
});
}
});
});
function toggleDropDown(menu) {
var isActive = $('a.active').length;
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
$(".main-container").removeClass("black-bg");
if (menu.hasClass('active')) {
menu.removeClass('active');
} else {
$('a.active').removeClass('active');
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500, function() {
$(".main-container").addClass("black-bg");
});
}
});
if (!isActive) {
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500, function() {
$(".main-container").addClass("black-bg");
});
}
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-size: 12px;
font-family: Arial;
}
.nav-wrapper {
width: 100%;
overflow: hidden;
background: #424242;
}
nav {
width: 100%;
margin: auto;
overflow: hidden;
background: #424242;
}
.nav-content {
width: 100%;
z-index: 999;
background: #ccc;
}
.top-bar-section {
float: right;
}
.top-bar-section a.active {
background: #c8c8c8;
color: #000;
}
.showup {
display: none;
background: #ccc;
position: absolute;
width: 100%;
top: 50px;
left: 0;
z-index: 99;
padding: 30px 15px 30px 20px;
}
p {
font-size: 14px;
line-height: 1.4;
}
li.nav-item {
display: inline-block;
background: #f5f5f5;
}
li.nav-item a {
display: block;
text-decoration: none;
padding: 10px;
}
.main-container {
width: 80%;
height: 400px;
margin: auto;
}
.black-bg {
background: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav-wrapper">
<nav>
<div class="top-bar-section">
<ul>
<li class="nav-item">
<a href="#" class="click">Nav item 1</a>
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 1.
</p>
</div>
</div>
</li>
<li class="nav-item">
<a href="#" class="click">Nav item 2</a>
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 2.
</p>
</div>
</div>
</li>
<li class="nav-item">
<a href="#" class="click">Nav item 3</a>
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 3.
</p>
</div>
</div>
</li>
<li class="nav-item">
<a href="#" class="click">Nav item 4</a>
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 4.
</p>
</div>
</div>
</li>
</ul>
</div>
</nav>
</div>
<div class="main-container">
</div>
Upvotes: 1
Reputation: 4305
Check if there are any .active
, if yes, setTimeout()
with 900 miliseconds, if no, setTimeout()
with 0 miliseconds(actually it would be 4 miliseconds but it would never 100% accurate).
$(document).ready(function() {
$(".click").on("click", function(evt) {
evt.stopPropagation();
var th = $(this);
if (th.hasClass("active")) {
th.removeClass("active");
th.parent().find(".showup").slideUp(900);
$(".main-container").removeClass("black-bg");
} else {
let ms = $(".active").length>0 ? 900:0;
$(".active").removeClass("active");
$(".showup").slideUp(900);
$(".main-container").removeClass("black-bg");
setTimeout(function() {
th.addClass("active");
th.parent().find(".showup").slideDown(900);
$(".main-container").addClass("black-bg");
}, ms);
}
});
$(".showup").on("click", function(evt) {
evt.stopPropagation();
});
});
$(document).on("click", function() {
$(".active").parent().find(".showup").slideUp(900);
$(".active").toggleClass("active");
if ($(".main-container").hasClass("black-bg")) {
$(".main-container").toggleClass("black-bg");
}
});
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.nav-wrapper {
width: 100%;
overflow: hidden;
background: #424242;
}
nav {
/*width: 1024px;*/
margin: auto;
overflow: hidden;
background: #424242;
}
.nav-content {
width: 100%;
z-index: 999;
background: #ccc;
}
.top-bar-section {
float: right;
}
.top-bar-section a.active {
background: #f00;
}
.showup {
display: none;
background: #ccc;
position: absolute;
width: 100%;
top: 70px;
left: 0;
z-index: 99;
padding: 30px 15px 30px 20px;
}
p {
font-size: 14px;
line-height: 1.4;
}
li.nav-item {
display: inline-block;
background: #f5f5f5;
}
li.nav-item a {
display: block;
text-decoration: none;
padding: 10px;
}
.main-container {
width: 80%;
height: 400px;
margin: auto;
}
.black-bg {
background: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="nav-wrapper">
<nav>
<div class="top-bar-section">
<ul>
<li class="nav-item">
<a href="#" class="click">Nav item 1</a>
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 1.
</p>
</div>
</div>
</li>
<li class="nav-item">
<a href="#" class="click">Nav item 2</a>
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 2.
</p>
</div>
</div>
</li>
<li class="nav-item">
<a href="#" class="click">Nav item 3</a>
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 3.
</p>
</div>
</div>
</li>
<li class="nav-item">
<a href="#" class="click">Nav item 4</a>
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 4.
</p>
</div>
</div>
</li>
</ul>
</div>
</nav>
</div>
<div class="main-container">
</div>
Upvotes: 1