I am trying to create a nav bar with submenus but when I open the submenu I am not able to click on the list. The hovered list isn't staying open for me to click on it.
$('.one').hover(function(){
$(this).next().show();
}, function(){
$(this).next().hide();
});
body {
font-family: Arial, Helvetica, sans-serif;
}
.navbar {
overflow: hidden;
background-color: #333;
}
.navbar a {
float: left;
font-size: 16px;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.dropdown {
float: left;
overflow: hidden;
}
.dropdown .dropbtn {
font-size: 16px;
border: none;
outline: none;
color: white;
padding: 14px 16px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
.navbar a:hover, .dropdown:hover .dropbtn {
background-color: red;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #ddd;
}
.dropdown:hover .dropdown-content {
display: block;
}
.yo {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
left: 100%;
top: 30%;
}
.yo a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div class="navbar">
Home
News
<div class="dropdown">
<button class="dropbtn">Dropdown
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
Link 1
<div class="yo">
Link 1
Link 2
Link 3
</div>
Link 2
<div class="yo">
Link 4
Link 5
Link 6
</div>
Link 3
<div class="yo">
Link 7
Link 8
Link 9
</div>
</div>
</div>
</div>
<h3>Dropdown Menu inside a Navigation Bar</h3>
<p>Hover over the "Dropdown" link to see the dropdown menu.</p>
</body>
</html>
When I click on Dropdown--> Hover over Link 1 and now I want to select Link 1 in the sub-submenu that opens when you hover. Is there anyways I can keep the link open long enough to click the link.
Notice how the "dropdown" link has everything within it's DIV and just with css :hover it is showing/hiding the menu. You need to put the button "one" and submenu "yo" both in one div and do css :hover on the div. No need jquery.
The html:
<div class="navbar">
Home
News
<div class="dropdown">
<button class="dropbtn">Dropdown
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
<div class="submenu">
Link 1
<div class="yo">
Link 1
Link 2
Link 3
</div>
</div>
<div class="submenu">
Link 2
<div class="yo">
Link 4
Link 5
Link 6
</div>
</div>
<div class="submenu">
Link 3
<div class="yo">
Link 7
Link 8
Link 9
</div>
</div>
</div>
</div>
</div>
Add this css:
.submenu:hover .yo {
display: block;
}
Remove the JQuery hover.
Here is the working fiddle
Related
I have one dropdown working, but the second dropdown interferes with the first one. Still very new to JavaScript and don't have time to learn it properly at the moment, so help is much appreciated!
Dropdown CSS
.dropdown{
display:inline-block;
}
.dropdown .dropbtn {
cursor: pointer;
font-size: 100%;
border: none;
outline: none;
color: white;
padding: 10px 20px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
.navbar a:hover, .dropdown:hover .dropbtn, .dropbtn:focus {
background-color: #FFA036;
color:black;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
border:1px solid black;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #ddd;
}
.show {
display: block;
}
Navigation bar HTML
I have one dropdown working well, but as soon as I put a second one in, it interferes with the first. I also have links in the bar which don't need dropdowns.
<nav>
Link
<div class="dropdown">
<button class="dropbtn" onclick="myFunction()"> Link
</button>
<div class="dropdown-content" id="myDropdown">
Link
Link
Link
Link
Link
Link
Link
Link
Link
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction()"> Link
</button>
<div class="dropdown-content" id="myDropdown">
Link
Link
Link
Link
</div>
</div>
Link
Link
Link
<a href="Link"> Link
</a>
</nav>
JavaScript
I think what is going wrong is something in the JavaScript here. A simple fix to make the JavaScript apply to all dropdowns would be great!
<script>
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var myDropdown = document.getElementById("myDropdown");
if (myDropdown.classList.contains('show')) {
myDropdown.classList.remove('show');
}
}
}
</script>
function myFunction(event) {
var parentDiv = event.target.parentNode;
var currentDropdown = parentDiv.querySelector(".dropdown-content");
currentDropdown.classList.toggle("show");
var dropdownContent = document.querySelectorAll(".dropdown .dropdown-content");
dropdownContent.forEach(function (dropdownContentItem) {
if (currentDropdown != dropdownContentItem) {
dropdownContentItem.classList.remove("show");
}
})
}
window.onclick = function (e) {
if (!e.target.parentNode.classList.contains('dropdown')) {
var dropdownContent = document.querySelectorAll(".dropdown .dropdown-content");
dropdownContent.forEach(function (dropdownContentItem) {
dropdownContentItem.classList.remove("show");
})
}
}
<nav>
Link
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)"> Link
</button>
<div class="dropdown-content" id="myDropdown">
Link
Link
Link
Link
Link
Link
Link
Link
Link
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)"> Link
</button>
<div class="dropdown-content" id="myDropdown">
Link
Link
Link
Link
</div>
</div>
Link
Link
Link
<a href="Link"> Link
</a>
</nav>
You can't use identical IDs for multiple elements.
var prevMenu = null; //we will store last opened menu here
function myFunction(link)
{
var menu = link.parentNode.getElementsByClassName("dropdown-content")[0];
if (!menu)
return;
if (prevMenu && prevMenu !== menu)
prevMenu.classList.remove('show'); //close previous menu
prevMenu = menu;
menu.classList.toggle("show");
}
window.onclick = function(e) {
if (!e.target.matches('.dropbtn') && prevMenu) {
prevMenu.classList.remove('show');
}
}
.dropdown
{display:inline-block;
}
.dropdown .dropbtn {
cursor: pointer;
font-size: 100%;
border: none;
outline: none;
color: black;
padding: 10px 20px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
.navbar a:hover, .dropdown:hover .dropbtn, .dropbtn:focus {
background-color: #FFA036;
color:black;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
border:1px solid black;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #ddd;
}
.show {
display: block;
}
<nav>
Link
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(this)"> Link1
</button>
<div class="dropdown-content">
sub Link 1.1
sub Link 1.2
sub Link 1.3
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(this)"> Link2
</button>
<div class="dropdown-content">
sub Link 2.1
sub Link 2.2
sub Link 2.3
</div>
</div>
Link
Link
Link
<a href="Link"> Link
</a>
</nav>
This question already has answers here:
How wide is the default `<body>` margin?
(4 answers)
What are the default margins for the html heading tags (<h1>, <h2>, <h3>, etc.)?
(4 answers)
Closed 2 years ago.
I am designing a website, as I am adding clickable button to it. My Nav-bar having some white-space above it.
Previously I have posted same question, but now I don't know what's wrong with my CSS. Please rectify or mention where my CSS is done wrong. I donot want to render my navbar, with white space above it.
So, Please change the CSS, and show me where I am doing error.
I also added css icon to it. As I
function myFunction(event) {
var clickedElement = event.target;
console.log(clickedElement);
if (clickedElement.nodeName != 'BUTTON') {
clickedElement = clickedElement.parentElement;
}
var dropdownElement = clickedElement.nextElementSibling;
dropdownElement.classList.add('tempClass'); //adding tempclass to avoid this in below loop
var allOtherDropdowns = document.getElementsByClassName('dropdown-content');
//close all other dropdowns
for (var i = 0; i < allOtherDropdowns.length; i++) {
if (!allOtherDropdowns[i].classList.contains('tempClass')) {
allOtherDropdowns[i].classList.remove('show');
}
}
dropdownElement.classList.toggle("show");
dropdownElement.classList.remove('tempClass'); //removing the temp class here
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var allDropdowns = document.getElementsByClassName('dropdown-content');
//close all other dropdowns
for (var i = 0; i < allDropdowns.length; i++) {
allDropdowns[i].classList.remove('show');
}
}
}
i{
width: 0;
height: 0;
border-style: solid;
border-width: 8px 5px 0 5px;
border-color: #ffffff transparent transparent transparent;
}
.icon{
position: relative;
/* Adjust these values accordingly */
top: 14px;
left: 9px;
}
nav {
height: 40px
overflow: hidden;
background-color: #333;
font-family: Arial, Helvetica, sans-serif;
}
nav a {
float: left;
font-size: 16px;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.dropdown {
float: left;
overflow: hidden;
}
.drop-btn{
float: right;
}
.dropdown .dropbtn {
cursor: pointer;
font-size: 14px;
border: none;
outline: none;
color: white;
padding: 10px 10px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
nav a:hover,
.dropdown:hover .dropbtn,
.dropbtn:focus {
background-color: red;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #ddd;
}
.show {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<nav>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)">Programming
<i class="icon"></i>
</button>
<div class="dropdown-content">
Java
C++
Python
Swift
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)">Platform
<i class="icon"></i>
</button>
<div class="dropdown-content">
Linux
Windows
Development Editor
</div>
</div>
<div class="dropdown">
<button class="dropbtn" >Algorithm
</button>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)">Upgrade 4
<i class="icon"></i>
</button>
<div class="dropdown-content">
item 10
item 11
item 12
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)">Upgrade 4
<i class="icon"></i>
</button>
<div class="dropdown-content">
item 10
item 11
item 12
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)">Upgrade 4
<i class="icon"></i>
</button>
<div class="dropdown-content">
item 10
item 11
item 12
</div>
</div>
<nav>
<h3>Dropdown Menu inside a Navigation Bar</h3>
<p>Click on the "Dropdown" link to see the dropdown menu.</p>
</body>
</html>
Your h3 with the text Dropdown Menu inside a Navigation Bar had a margin. Also your body had a small margin. Should be fine now.
function myFunction(event) {
var clickedElement = event.target;
//console.log(clickedElement);
if (clickedElement.nodeName != 'BUTTON') {
clickedElement = clickedElement.parentElement;
}
var dropdownElement = clickedElement.nextElementSibling;
dropdownElement.classList.add('tempClass'); //adding tempclass to avoid this in below loop
var allOtherDropdowns = document.getElementsByClassName('dropdown-content');
//close all other dropdowns
for (var i = 0; i < allOtherDropdowns.length; i++) {
if (!allOtherDropdowns[i].classList.contains('tempClass')) {
allOtherDropdowns[i].classList.remove('show');
}
}
dropdownElement.classList.toggle("show");
dropdownElement.classList.remove('tempClass'); //removing the temp class here
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var allDropdowns = document.getElementsByClassName('dropdown-content');
//close all other dropdowns
for (var i = 0; i < allDropdowns.length; i++) {
allDropdowns[i].classList.remove('show');
}
}
}
function myFunc(){return true}
h3,body,html{
margin:0;
padding:0;
}
i {
width: 0;
height: 0;
border-style: solid;
border-width: 8px 5px 0 5px;
border-color: #ffffff transparent transparent transparent;
}
.icon {
position: relative;
/* Adjust these values accordingly */
top: 14px;
left: 9px;
}
nav {
height: 40px overflow: hidden;
background-color: #333;
font-family: Arial, Helvetica, sans-serif;
}
nav a {
float: left;
font-size: 16px;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.dropdown {
float: left;
overflow: hidden;
}
.drop-btn {
float: right;
}
.dropdown .dropbtn {
cursor: pointer;
font-size: 14px;
border: none;
outline: none;
color: white;
padding: 10px 10px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
nav a:hover,
.dropdown:hover .dropbtn,
.dropbtn:focus {
background-color: red;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #ddd;
}
.show {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<nav>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)">Programming
<i class="icon"></i>
</button>
<div class="dropdown-content">
Java
C++
Python
Swift
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)">Platform
<i class="icon"></i>
</button>
<div class="dropdown-content">
Linux
Windows
Development Editor
</div>
</div>
<div class="dropdown">
<button class="dropbtn">Algorithm
</button>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)">Upgrade 4
<i class="icon"></i>
</button>
<div class="dropdown-content">
item 10
item 11
item 12
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)">Upgrade 4
<i class="icon"></i>
</button>
<div class="dropdown-content">
item 10
item 11
item 12
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction(event)">Upgrade 4
<i class="icon"></i>
</button>
<div class="dropdown-content">
item 10
item 11
item 12
</div>
</div>
<nav>
<h3>Dropdown Menu inside a Navigation Bar</h3>
<p>Click on the "Dropdown" link to see the dropdown menu.</p>
</body>
</html>
I am copying the code and made possible change in w3schools code. The Dropdown 2, and Dropdown 3 button is not working.
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var myDropdown = document.getElementById("myDropdown");
if (myDropdown.classList.contains('show')) {
myDropdown.classList.remove('show');
}
}
}
.navbar {
overflow: hidden;
background-color: #333;
font-family: Arial, Helvetica, sans-serif;
}
.navbar a {
float: left;
font-size: 16px;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.dropdown {
float: left;
overflow: hidden;
}
.dropdown .dropbtn {
cursor: pointer;
font-size: 16px;
border: none;
outline: none;
color: white;
padding: 14px 16px;
background-color: inherit;
font-family: inherit;
margin: 0;
}
.navbar a:hover, .dropdown:hover .dropbtn, .dropbtn:focus {
background-color: red;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #ddd;
}
.show {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<div class="navbar">
<div class="dropdown">
<button class="dropbtn" onclick="myFunction()">Dropdown 1
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content" id="myDropdown">
Link 1
Link 2
Link 3
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction()">Dropdown 2
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content" id="myDropdown">
Link 1
Link 2
Link 3
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction()">Dropdown 3
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content" id="myDropdown">
Link 1
Link 2
Link 3
</div>
</div>
</div>
</body>
</html>
The problem is that all 3 of your drop downs have the same id, which is not allowed. And since all 3 buttons use the same callback and that callback specifically toggles the visibility of that reused id, the system stops when it finds the first matching element (because there should never be more than one element with the same id in the first place).
The reality is that using ids in the first place, while it seems like an easy approach, causes brittle code that doesn't scale (as you've found), so avoid ids and use CSS classes and the hierarchy of your HTML elements as your methods for finding elements.
Also, never use getElementsByClassName() or inline HTML event attributes.
Do yourself a favor and stay as far away from W3 Schools as you can as it is well-known to have incomplete, inaccurate, or just plain wrong information. Instead, you'll get much more comprehensive and up to date information from The Mozilla Developers Network (MDN), who are the stewards of the JavaScript language.
See the comments below for details:
// Set your events up in JavaScript, not with HTML event attributes
document.addEventListener("click", function(event) {
// Loop over all the menus
document.querySelectorAll(".dropdown-content").forEach(function(dd){
dd.classList.remove("show"); // Hide the menu
});
// If the clicked element was a button
if (event.target.classList.contains('dropbtn')) {
// Show just the menu that corresponds to the clicked button
event.target.nextElementSibling.classList.toggle("show");
}
});
.dropbtn {
background-color: #3498DB;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #2980B9;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #ddd;}
.show {display: block;}
<div class="dropdown">
<button class="dropbtn">Dropdown 1</button>
<div class="dropdown-content">
Home 1
About 1
Contact 1
</div>
</div>
<div class="dropdown">
<button class="dropbtn">Dropdown 2</button>
<div class="dropdown-content">
Home 2
About 2
Contact 2
</div>
</div>
<div class="dropdown">
<button class="dropbtn">Dropdown 3</button>
<div class="dropdown-content">
Home 3
About 3
Contact 3
</div>
</div>
You have to differentiate your menus somehow. I used a data-target attribute. Also, you need to hide any visible menus before showing. About the button look, just change the css of .dropbtn to your liking.
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction(el) {
var currentMenu = document.querySelector(".dropdown-content.show");
if (currentMenu) currentMenu.classList.toggle("show");
document.getElementById(el.dataset.target).classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
.dropbtn {
background-color: #3498DB;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover,
.dropbtn:focus {
background-color: #2980B9;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {
background-color: #ddd;
}
.show {
display: block;
<div class="dropdown">
<button onclick="myFunction(this)" data-target="dropdown1" class="dropbtn">Dropdown 1</button>
<div id="dropdown1" class="dropdown-content">
Home 1
About 1
Contact 1
</div>
</div>
<div class="dropdown">
<button onclick="myFunction(this)" data-target="dropdown2" class="dropbtn">Dropdown 2</button>
<div id="dropdown2" class="dropdown-content">
Home 2
About 2
Contact 2
</div>
</div>
<div class="dropdown">
<button onclick="myFunction(this)" data-target="dropdown3" class="dropbtn">Dropdown 3</button>
<div id="dropdown3" class="dropdown-content">
Home 3
About 3
Contact 3
</div>
</div>
You can use .nextElementSibling ==> https://developer.mozilla.org/en-US/docs/Web/API/NonDocumentTypeChildNode/nextElementSibling
in your case
const allButtons = document.querySelectorAll('button.dropbtn');
allButtons.forEach(btn=>
{
btn.onclick=()=>{
allButtons.forEach(btn_X=>
{
let divContent = btn_X.nextElementSibling
if ( btn===btn_X) divContent.classList.toggle('show')
else divContent.classList.remove('show')
})
}
})
// Close the dropdown if the user clicks outside of it
window.onclick =e=>
{
if (e.target.matches('.dropbtn')) return
allButtons.forEach(btn=>btn.nextElementSibling.classList.remove('show'))
}
.dropbtn {
background-color: #3498DB;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #2980B9;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #ddd;}
.show {display: block; }
<div class="dropdown">
<button class="dropbtn">Dropdown 1</button>
<div class="dropdown-content">
Home 1
About 1
Contact 1
</div>
</div>
<div class="dropdown">
<button class="dropbtn">Dropdown 2</button>
<div class="dropdown-content">
Home 2
About 2
Contact 2
</div>
</div>
<div class="dropdown">
<button class="dropbtn">Dropdown 3</button>
<div class="dropdown-content">
Home 3
About 3
Contact 3
</div>
</div>
I am a newbie in coding and I wonder if it's possible to create multiple dropdown menus, and whenever you click outside an opened box, I want it to be collapsed. I am sharing the code I wrote but it's not working since one dropdown is collapsing when clicking outside, but the other one isn't. Can you help me with that? I'm sharing the code and I want 3 dropdown menus. I'm struggling with this for weeks now and I haven't succeeded yet. Thanks in advance!
HTML Code
<div class="container">
<span class="Agencymenu">Home</span>
<span class="Agencymenu">News</span>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction()">Team 1</button>
<div class="dropdown-content" id="myDropdown">
<span class="Agencymenu">Link 1</span>
<span class="Agencymenu">Link 2</span>
<span class="Agencymenu">Link 3</span>
</div>
</div>
<div class="dropdown2">
<button class="dropbtn2" onclick="myFunction2()">Team 2</button>
<div class="dropdown-content2" id="myDropdown2">
<span class="Agencymenu">Link 1</span>
<span class="Agencymenu">Link 2</span>
<span class="Agencymenu">Link 3</span>
</div>
</div>
</div>
CSS Code
.Agencymenu {
font-family: 'AGENCYB' !important;
font-weight: bold;
font-size: 24pt;
color: #FFFFFF;
}
.container {
overflow: hidden;
background-color: #30333c;
font-family: Arial;
}
.container a {
float: left;
font-size: 16px;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.dropdown {
float: left;
overflow: hidden;
}
.dropdown .dropbtn {
cursor: pointer;
font-size: 16px;
border: none;
outline: none;
color: white;
padding: 14px 16px;
background-color: inherit;
font-family:AGENCYB;
font-size:30px;
}
.container a:hover, .dropdown:hover .dropbtn {
background-color: #0C0;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #30333c;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {
background-color: #ddd;
}
.show {
display: block;
}
.container2 {
overflow: hidden;
background-color: #30333c;
font-family: Arial;
}
.container2 a {
float: left;
font-size: 16px;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.dropdown2 {
float: left;
overflow: hidden;
}
.dropdown2 .dropbtn2 {
cursor: pointer;
font-size: 16px;
border: none;
outline: none;
color: white;
padding: 14px 16px;
background-color: inherit;
font-family:AGENCYB;
font-size:30px;
}
.container2 a:hover, .dropdown2:hover .dropbtn2 {
background-color: #0C0;
}
.dropdown-content2 {
display: none;
position: absolute;
background-color: #30333c;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content2 a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content2 a:hover {
background-color: #0C0;
}
.show2 {
display: block;
}
JS Code:
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show2");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var myDropdown = document.getElementById("myDropdown");
if (myDropdown.classList.contains('show2')) {
myDropdown.classList.remove('show2');
}
}
}
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction2() {
document.getElementById("myDropdown2").classList.toggle("show2");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn2')) {
var myDropdown2 = document.getElementById("myDropdown2");
if (myDropdown2.classList.contains('show2')) {
myDropdown2.classList.remove('show2');
}
}
}
if you are okay using CSS only solution and you need dropdown on hover, you can simply use this code
.dropdown:hover .dropdown-content {display: block}
here is the fiddle https://jsfiddle.net/hkred6d7/1/
if you need it on click, let me know here in comment. it will require JS
It would be a lot easier with jQuery, but here is an example with vanilla JS. The key here is to reuse a css class for all dropdowns
https://jsfiddle.net/fyjjzhqw/
//HTML
<body>
<div class="wrapper">
<div class="Dropdown">
<div class="Dropdown__btn">Dropdown 1</div>
<ul class="Dropdown__list">
<li>Item A</li>
<li>Item B</li>
<li>Item C</li>
</ul>
</div>
<div class="Dropdown">
<div class="Dropdown__btn">Dropdown 2</div>
<ul class="Dropdown__list">
<li>Item A</li>
<li>Item B</li>
<li>Item C</li>
</ul>
</div>
<div class="Dropdown">
<div class="Dropdown__btn">Dropdown 3</div>
<ul class="Dropdown__list">
<li>Item A</li>
<li>Item B</li>
<li>Item C</li>
</ul>
</div>
</div>
</body>
// CSS
.Dropdown__list {
display: none
}
.is-opened.Dropdown .Dropdown__list {
display: block
}
//JS
var dropdowns = document.querySelectorAll('.Dropdown');
var closeAll = function() {
dropdowns.forEach( function(current) {
current.classList.remove('is-opened')
})
}
var toggleDropdown = function(e) {
closeAll();
var dropdown = e.currentTarget.parentElement;
dropdown.classList.toggle('is-opened')
}
for (i = dropdowns.length - 1; i >= 0; i--) {
dropdowns[i].querySelector('.Dropdown__btn').addEventListener('click', toggleDropdown)
}
you can try using this https://jsfiddle.net/aswin_89/hkred6d7/9/
modified your JS a bit
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
event.target.nextElementSibling.classList.toggle("show2");
}
function clearClasses (target){
document.querySelectorAll('.dropdown-content.show2').forEach((item)=>{
if(event.target.nextElementSibling !== item)
item.classList.remove('show2');
})
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
clearClasses(event.target.nextElementSibling);
}
I'm working on a site to learn more about javascript but I dont know how to fix this. If you look at the fiddlle and try the nav you're self you'll know what im talking about(if not, try hover on Multiplier and try to click Quadruple).
Also the .slideUp() seems glitch and I don't know why. I want it to look like it slidesdown from the nav and slides back up into the nav.
So how would you fix these 2 issues?
https://jsfiddle.net/26L2h6zg/
// Drop down menu
$(".shopDrop").hide();
$(".shop ul li").hover(function(){
$(this).find(".shopDrop").slideDown();
}, function(){
$(this).find(".shopDrop").slideUp();
});
// Drop down menu info
$(".shopDrop a").hover(function(){
$(this).next(".shopHoverInfo").fadeIn("slow");
}, function(){
$(this).next(".shopHoverInfo").fadeOut("slow");
});
// Drop down menu
$(".shopDrop").hide();
$(".shop ul li").hover(function(){
$(this).find(".shopDrop").stop(true).slideDown();
}, function(){
$(this).find(".shopDrop").stop(true).slideUp();
});
// Drop down menu info
$(".shopDrop a").hover(function(){
//$(this).stop(true, true);
$(this).next().stop(true).fadeIn("slow");
}, function(){
//$(this).stop(true);
$(this).next().stop(true).fadeOut("slow");
});
nav.shop {
width: 100%;
height: 100px;
background: #182024;
margin: 0;
}
nav.shop ul {
width: 960px;
list-style-type: none;
margin: 0 auto;
padding: 0;
}
nav.shop ul li {
display: inline-block;
vertical-align: top;
padding-left: 25px;
}
nav.shop ul li h1 {
font-size: 35px;
margin-right: 20px;
}
nav.shop ul li h2 {
color: #fff;
text-decoration: none;
font-size: 35px;
margin-left: 10px;
}
nav.shop ul li a {
color: #fff;
text-decoration: none;
font-size: 35px;
padding-bottom: 10px;
padding-top: 10px;
display: block;
}
.shopDrop {
position: absolute;
background: #182024;
padding: 30px 10px 0 10px;
margin-top: -30px;
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
}
nav.shop ul li div a {font-size: 20px;}
nav.shop ul li div span {font-size: 15px;}
#shopMultiplier{border-bottom: 5px solid #CA2525;}
#shopAutoclicker{border-bottom: 5px solid #2596CA;}
#shopFarms{border-bottom: 5px solid #CAB125;}
#shopSkills{border-bottom: 5px solid #35CA25;}
.shopHoverInfo {
display: none;
width: 150px;
background: #1C262A;
text-align: center;
padding: 0;
color: #fff;
}
.shopHoverInfo h3 {
font-size: 17px;
background: #CA2525;
margin: 0;
padding: 5px;
border-top-right-radius: 10px;
border-top-left-radius: 10px;
}
.shopHoverInfo h4 {
font-size: 17px;
margin: 0;
background: #EED634;
}
.shopHoverInfo p {
font-size: 15px;
}
<nav class="shop">
<ul>
<li><h1>SHOP</h1></li>
<li>
<h2 href="#" id="shopMultiplier">Multiplier</h2>
<div class="shopDrop">
Double knowledge <span>☆</span>
<div class="shopHoverInfo">
<h3>Double Knowledge</h3>
<h4>Price: <span id="shopDoublePrice"></span> knowledge</h4>
<p>When you click you get 2x knowledge</p>
</div>
Triple knowledge <span>☆</span>
<div class="shopHoverInfo">
<h3>Triple Knowledge</h3>
<h4>Price: <span id="shopTriplePrice"></span> knowledge</h4>
<p>When you click you get 3x knowledge</p>
</div>
Quadruple knowledge <span>☆</span>
<div class="shopHoverInfo">
<h3>Quadruple Knowledge</h3>
<h4>Price: <span id="shopQuadruplePrice"></span> knowledge</h4>
<p>When you click you get 4x knowledge</p>
</div>
</div>
</li>
<li><h2 href="#" id="shopAutoclicker">Auto-clicker</h2></li>
<li>
<h2 href="#" id="shopFarms">Farms</h2>
<div class="shopDrop">
Simple mind's <span></span>
<div class="shopHoverInfo">
<h3>Simple Mind</h3>
<p>Simple mind farms 1 knowledge each second.</p>
</div>
intelligent mind's <span></span>
<div class="shopHoverInfo">
<h3>Intelligent Mind</h3>
<p>Intelligent mind farms 2 knowledge each second.</p>
</div>
</div>
</li>
<li>
<h2 href="#" id="shopSkills">Skills</h2>
<!-- <div class="shopDrop">
Simple mind's <span></span>
</div> -->
</li>
</ul>
</nav>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
It would be easier to make HTML according to your needs. Hope this helps.