Reputation: 53
I am developing this jQuery script approach for a website drop down menu. I have come across a hiccup in the code that I cannot seem to get past.
Additional Information:
This is the current script with comments. The problem seems to lay within, $(".is-open").hide();
. If I remove this line from the script it restores the click to open and click to close functionality, however, when clicking from "DROP 1" to "DROP 2" the drop down menus will stay open.)
<script>
// this is the function caller for click into drop down menu
$(document).ready(function(){
// this to function call targets the drop down menu by elements
$("li:has(ul)").click(function(){
// (IMPORTANT) code to hide existing open drop down menu before displaying new drop down menu
$(".is-open").hide();
// code to toggle menu from drop down ROOT
$(this).find(".is-open").toggle();
});// END: .click
});// END: .ready
//this script closes menu when clicked outside of drop down menu.
$(document).on("click", function(event){
var $triggerOn = $(".dropdown");
if($triggerOn !== event.target && !$triggerOn.has(event.target).length){
$(".is-open").hide();
}// END: if statement
});// END: .on
</script>
Here is the full html document.
<!DOCTYPE html>
<html>
<head>
<style>
li > ul{display:none;}
.show {display:block;}
.sub-nav ul {
background: #efefef;
background: linear-gradient(top, #efefef 0%, #bbbbbb 100%);
background: -moz-linear-gradient(top, #efefef 0%, #bbbbbb 100%);
background: -webkit-linear-gradient(top, #efefef 0%,#bbbbbb 100%);
box-shadow: 0px 0px 9px rgba(0,0,0,0.15);
padding: 0 20px;
border-radius: 0px;
list-style: none;
position: relative;
}
.sub-nav ul:after {content: ""; clear: both; display: block;}
li {float: left;}
.sub-nav ul li:hover {
background: #4b545f;
background: linear-gradient(top, #4f5964 0%, #5f6975 40%);
background: -moz-linear-gradient(top, #4f5964 0%, #5f6975 40%);
background: -webkit-linear-gradient(top, #4f5964 0%,#5f6975 40%);
}
.sub-nav ul li:hover a {color: #fff;}
.sub-nav ul li a {
display: block;
padding: 20px 40px;
color: #757575;
text-decoration: none;
}
.sub-nav ul ul {
background: #5f6975;
border-radius: 0px;
padding: 0;
position: absolute;
top: 100%;
}
.sub-nav ul ul li {
float: none;
border-top: 1px solid #6b727c;
border-bottom: 1px solid #575f6a;
position: relative;
}
.sub-nav ul ul li a {padding: 15px 40px; color: #fff;}
.sub-nav ul ul li a:hover {background: #4b545f;}
</style>
</head>
<body>
<!-- START: nav -->
<div class="sub-nav">
<div class="container">
<ul>
<li class="active"><a href="#">ROOT 1</a></li>
<li><a href="#">ROOT 2</a></li>
<li><a href="#">ROOT 3</a></li>
<li><a href="#">ROOT 4</a></li>
<li><a href="#">ROOT 5</a></li>
<li class="dropdown"><a href="#">DROP 1</a>
<ul class="is-open">
<li><a href="#">SUB MENU 1</a></li>
<li><a href="#">SUB MENU 2</a></li>
<li><a href="#">SUB MENU 3</a></li>
<li><a href="#">SUB MENU 4</a></li>
</ul>
</li>
<li class="dropdown"><a>DROP 2</a>
<ul class="is-open">
<li><a href="#">SUB MENU LONG TITLE 1</a></li>
<li><a href="#">SUB MENU LONG TITLE 2</a></li>
<li><a href="#">SUB MENU LONG TITLE 3</a></li>
</ul>
</li>
</ul>
</div>
</div>
<!-- END: nav -->
</body>
</html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
// toggle drop down
$(document).ready(function(){
$("li:has(ul)").click(function(){
$(".is-open").hide();
$(this).find(".is-open").toggle();
});
});
// close menu when clicked outside of drop down menu
$(document).on("click", function(event){
var $triggerOn = $(".dropdown");
if($triggerOn !== event.target && !$triggerOn.has(event.target).length){
$(".is-open").hide();
}
});
</script>
Upvotes: 4
Views: 2656
Reputation: 167210
I guess I have the water for your hiccup. The problem is with this piece of code:
$(document).ready(function(){
$("li:has(ul)").click(function(){
$(".is-open").hide();
$(this).find(".is-open").toggle();
});
});
No matter what you do, it always closes everything and opens it. Adding a condition like this, makes it work:
$(document).ready(function(){
$("li:has(ul)").click(function(){
if ($(this).find(".is-open").is(":visible")) {
$(".is-open").hide();
} else {
$(".is-open").hide();
$(this).find(".is-open").toggle();
}
});
});
Output: http://output.jsbin.com/jodevoropu
Also I changed the following:
<li id="dropdown"><a href="#">DROP 1</a> <!-- Wrong -->
<li class="dropdown"><a href="#">DROP 1</a> <!-- Right -->
psst: Now mark this as complete! :P
- Drop down menu expands upon clicking root level menu element. [COMPLETE]
- Drop down menu closes upon clicking same root level menu element. [COMPLETE]
- Drop down menu closes when clicking from one root level menu element to another. [COMPLETE]
- Drop down menu closes upon clicking outside of the drop down menu area. [COMPLETE]
- Support multiple drop down menus from root level menu. [COMPLETE]
Upvotes: 2