My website navigation should have three main links on the left ("Menu", "Coffee", and "Our Story"), and two on the right ("Wholesale" and "Talk to Us"). The first two ("Menu" and "Coffee") should be dropdown menus, however when I click "Menu" the dropdown menu only sometimes appears. When I click "Coffee" the dropdown sometimes appears too, but it shows the dropdown links for "Menu" instead of it's own.
My first thought is that maybe I need two separate functions for "Menu" and "Coffee"? Is there a way to properly display the dropdown links on click? And can I also somehow display the dropdown on hover?
Thank you in advanced.
HTML:
<nav class ="navbar">
<ul class="left-nav">
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn"><li>Menu</li></button>
<div id="myDropdown" class="dropdown-content">
Drinks
Pastries
Catering
</div>
</div>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn"><li>Coffee</li></button>
<div id="myDropdown" class="dropdown-content">
Blends
Beanie's Brand
</div>
</div>
<li>Our Story</li>
</ul>
<ul class="right-nav">
<li>Wholesale</li>
<li>Talk To Us</li>
</ul>
</nav>
CSS:
.navbar {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.navbar ul {
top: 170px;
position: fixed;
z-index: 1;
}
.left-nav {
flex: 50%;
display: block;
margin-right: auto;
float: left;
left: 0px;
}
.right-nav {
flex: 50%;
display: block;
float: right;
right: 50px;
}
.navbar li {
list-style-type: none;
}
.navbar ul li {
display: inline-block;
}
.navbar a {
text-decoration: none;
/* color: rgb(255, 180, 148); */
color: white;
margin: 20px;
font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, serif;
font-weight: 530;
font-size: 20px;
}
.navbar a:hover {
color: hsl(39, 92%, 70%);
}
/* Dropdown Navigation */
.dropbtn {
background-color: rgba(255,255,255,0);
color: white;
font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, serif;
font-weight: 530;
font-size: 20px;
border: none;
cursor: pointer;
padding-right: 15px;
padding-left: 20px;
}
.dropbtn:hover, .dropntn:focus {
color: hsl(39, 92%, 70%);
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 2;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
display: block;
}
.show {display:block;}
Javascript:
/* Toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown menu 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');
}
}
}
}
There should be only one element with same id on a page, you should target the dropdown differently:
function myFunction(element) {
element.parentNode.querySelector('.dropdown-content').classList.toggle("show");
}
<button onclick="myFunction(this)" class="dropbtn"><li>Coffee</li></button>
Related
I made a nav bar using nav and li tags, including a notifications icon, I am trying to make notifications nested list to show notifications, and use JavaScript to toggle/hide the menu, so far no luck. I've been looking for snippets online to support my logic, but I am stuck in the styling part and the JavaScript functionality. code below:
/* 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');
}
}
}
html {
scroll-behavior: smooth;
}
* {
font-family: 'Roboto', sans-serif;
font-style: normal;
padding: 0;
margin: 0;
text-decoration: none;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1;
}
::-webkit-scrollbar {
width: 1.32vmin;
}
/*
::-webkit-scrollbar-track{
border: 0.53vmin solid rgba(7, 67, 146, 0.17);
box-shadow: inset 0 0 0.33vmin 0.26vmin rgba(7, 67, 146, 0.17);
}
*/
::-webkit-scrollbar-thumb {
background: #074392;
border-radius: 0vmin;
}
::-webkit-scrollbar-button {
height: 7.45vmin;
background: #074392;
}
body {
font-weight: 400;
font-size: 2.12vmin;
background-color: #FFFFFF;
/*overflow: hidden;*/
height: 100%;
}
h1 {
margin-left: 3vmin;
}
h5 {
margin: 2vmin 3vmin;
position: absolute;
width: 14.72vmin;
font-weight: 500;
font-size: 2.65vmin;
letter-spacing: 0.79vmin;
color: #FFFFFF;
display: inline;
}
nav {
background-color: #074392;
height: 7.42vmin;
width: 100%;
/*position: relative;*/
/*overflow: hidden;*/
position: sticky;
top: 0;
}
img.logo {
margin: 1.855vmin 3vmin;
height: 3.5vmin;
width: 7vmin;
}
nav ul {
float: right;
margin: 1.855vmin 2vmin;
}
nav ul li {
display: inline-block;
}
nav ul li::before {
content: " ";
padding: 0vmin 0.5vmin;
}
nav ul li a {
color: white;
/*margin: 0vmin 1vmin;*/
/*border-top-left-radius: 1.326vmin;
border-top-right-radius: 1.326vmin;
border-bottom-left-radius: 1.326vmin;
border-bottom-right-radius: 1.326vmin;*/
}
a.active,
a:hover {
font-variation-settings: 'FILL' 1;
}
.checkbtn {
color: #ffffff;
float: left;
cursor: pointer;
display: none;
margin: 1.855vmin 3vmin;
}
#check {
display: none;
}
#check:checked~ul {
left: 0;
}
.dropdown {}
.dropdown .dropbtn {
cursor: pointer;
border: none;
outline: none;
background-color: #074392;
color: #FFFFFF;
}
.dropdown:hover .dropbtn,
.dropbtn:focus {
color: #FFFFFF;
font-variation-settings: 'FILL' 1;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #0743922B;
width: 37.5vmin;
overflow-wrap: break-word;
transform: translateX(-56%);
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: justify;
}
.dropdown-content a:hover {
background-color: #0743922B;
}
.show {
display: block;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD#20..48,100..700,0..1,-50..200" />
<div class="container">
<nav>
<input type="checkbox" id="check">
<label for="check" class="checkbtn">
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Menu">menu</i>
</label>
<h5>LOGO</h5>
<ul>
<li>
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Home">home</i>
</li>
<!-- <li> <i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Notifications">notifications</i> -->
<li class="dropdown"><button class="dropbtn" onclick="myFunction()"><i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Notifications">notifications</i></button>
<div class="dropdown-content" id="myDropdown">
<div>Link 1</div>
<div>Link 2</div>
<div>Link asasdasdasdasdasdsadsadasdasdasdasd asddasdas asd asd asd dasd asd</div>
</div>
</li>
<li>
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Tasks">task</i>
</li>
<li>
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Profile">person</i>
</li>
</ul>
<script type="text/javascript" src="JS/ActiveTab.js"></script>
<script type="text/javascript" src="JS/ToggleNotifications.js"></script>
</nav>
<main>
<h1>Example Page</h1>
</main>
</div>
By default set a display: none on the dropdown element and set a display: block on the hover pseudo-class of the dropdown element so when a hover event is triggered the dropdown appears.
Also, you can use classList.toggle method to remove if exists or to add if not exist the class.
Remove
Just add the following to the .css:
#myDropdown {
display: none;
}
#myDropdown.show {
display: block;
}
Remove onclick="myFunction()". And replace the .js with:
const myDropdown = document.getElementById('myDropdown')
addEventListener('click', event => {
let dropbtn = event.target.closest('button.dropbtn')
if (!dropbtn) return myDropdown.classList.remove('show')
console.log('hii')
myDropdown.classList.toggle('show')
})
I have been trying to solve this issue for some days now but just giving me a lot of time to crack my brain and yet doesn't get the solution to it.
What I want to solve is that, when I click on each button, I want its dropdown to show just below its own button rather than all the dropdown showing at the left side of the screen and secondly, when it show just below its button, the content should change.
Thanks.
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
let dropdowns = document.getElementsByClassName("dropdown-content");
let i;
for (i = 0; i < dropdowns.length; i++) {
let openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
};
nav {
display: flex;
}
.dropbtn {
font-size: 12px;
border: none;
outline: none;
text-align: center;
color: #f2f2f2;
width: 155px;
padding: 14px 16px;
background-color: inherit;
font-family: serif;
text-transform: capitalize;
border-right: 1px solid gray;
border-bottom: 1px solid gray;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #2980B9;
}
.dropdown {
position: relative;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 200px;
height: 200px;
overflow: hidden;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
border-radius: 10px;
padding-bottom: 20px;
padding-top: 40px;
opacity: .9;
}
.dropdown-content a {
color: blue;
padding: 12px 20px;
text-decoration: none;
display: block;
width: 100%;
font-size: 12px;
background-color: ;
border-bottom: 1px solid gray;
}
.dropdown a:hover {
background-color: gray;
}
.show {
display: block;
}
<nav>
<div class="dropdown">
<button class="dropbtn" id="active" onclick="myFunction()">new
</button>
<div class="dropdown-content" id="myDropdown">
link 1
link 2
link 3
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction()">fresh
</button>
<div class="dropdown-content" id="myDropdown">
link 4
link 5
link 6
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="myFunction()">naija
</button>
<div class="dropdown-content" id="myDropdown">
link 7
link 8
link 9
</div>
</div>
</nav>
What your code is doing right now is creating three dropdown elements. Then, when a button is clicked, you are executing myFunction(), which gets #myDropdown. An element's id is, quoting the MDN Docs, "unique in a document". However, you have three elements with the same ID. So, when you execute document.getElementById("myDropdown") on line two of your JS code, it will find the first instance of #myDropdown and toggle the show class on that one element.
The provided code has the following changes:
Removed inline events. It is better practice to use addEventListener instead of inline events like onclick in your HTML.
Better let and const usages.
const dropdowns = Array.from(document.getElementsByClassName("dropdown-content"));
const dropdownButtons = Array.from(document.getElementsByClassName('dropbtn'));
let currentDropdown = 0;
let dropdownAmount = 0;
dropdownButtons.forEach(function(dropdownBtn, index) {
dropdownBtn.addEventListener('click', function(e) {
e.stopPropagation();
dropdowns[index].classList.toggle('show');
currentDropdown = index;
dropdownAmount++;
if (dropdownAmount > 1) { // closes other dropdowns if more than one is open
for (let i = 0; i < dropdowns.length; i++) {
const openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show') && i !== currentDropdown) {
openDropdown.classList.remove('show');
}
}
dropdownAmount = 1;
}
});
});
window.addEventListener('click', function(event) {
for (let i = 0; i < dropdowns.length; i++) {
const openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
dropdownAmount = 0;
}
});
nav {
display: flex;
}
.dropbtn {
font-size: 12px;
border: none;
outline: none;
text-align: center;
color: #f2f2f2;
width: 155px;
padding: 14px 16px;
background-color: inherit;
font-family: serif;
text-transform: capitalize;
border-right: 1px solid gray;
border-bottom: 1px solid gray;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #2980B9;
}
.dropdown {
position: relative;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 200px;
height: 200px;
overflow: hidden;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
border-radius: 10px;
padding-bottom: 20px;
padding-top: 40px;
opacity: .9;
}
.dropdown-content a {
color: blue;
padding: 12px 20px;
text-decoration: none;
display: block;
width: 100%;
font-size: 12px;
background-color: ;
border-bottom: 1px solid gray;
}
.dropdown a:hover {
background-color: gray;
}
.show {
display: block;
}
<nav>
<div class="dropdown">
<button class="dropbtn" id="active">new</button>
<div class="dropdown-content">
link 1
link 2
link 3
</div>
</div>
<div class="dropdown">
<button class="dropbtn">fresh</button>
<div class="dropdown-content">
link 4
link 5
link 6
</div>
</div>
<div class="dropdown">
<button class="dropbtn"><i>naija</i></button> <!-- demonstration for op's problem -->
<div class="dropdown-content">
link 7
link 8
link 9
</div>
</div>
</nav>
EDIT: Fixed the code so that child elements of the .dropbtns also open the dropdown. The .dropbtn click event was working, but then it also fired the window click event. The window click event checked the event target, which was not a button, so it closed all the dropdowns. Now, if the .dropbtn click event is fired, e.stopPropagation is called which prevents the window click event from firing.
I started writing a responsive navigation bar (4 menu item) with two clickdowns. Now, I would like to add a third one. But when I add a third one, it won't dropdown. Earlier someone helped me with the second one (which also didn't drop down) and it works. So I thought I'd just copy the JS from the second one but that didn't work. Can someone tell me what I need to do in order for the third one to also dropdown? Thx!
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
/*If you bind 2 onclick then only last one will fire*/
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
removeShow("dropdown-content");
}
if (!event.target.matches('.dropbtn2')) {
removeShow("dropdown-content2");
}
}
function removeShow(className) {
var dropdowns = document.getElementsByClassName(className);
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
function myFunction2() {
document.getElementById("myDropdown2").classList.toggle("show");
}
/* Navigation */
.navbar-0 {
height: auto;
}
.navbar-1 {
text-align: center;
color: #FB4D4D;
padding: 0px;
}
.home,
.contact {
padding: 5px;
}
/* Dropdown Button */
.dropbtn {
text-align: center;
font-size: 15px;
font-family: 'Open Sans', sans-serif;
background-color: white;
color: #FB4D4D;
padding: 0px;
margin: 0px;
border: none;
cursor: pointer;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
margin: 5px;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: white;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: #FB4D4D;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {
display: block;
border: none;
}
/*2e drop*/
/* Dropdown Button */
.dropbtn2 {
font-size: 15px;
font-family: 'Open Sans', sans-serif;
background-color: white;
color: #FB4D4D;
padding: 0px;
margin: 0px;
border: none;
cursor: pointer;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
.dropdown2 {
position: relative;
margin: 5px;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content2 {
display: none;
position: absolute;
background-color: white;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content2 a {
color: #FB4D4D;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content2 a:hover {
background-color: #f1f1f1
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {
display: block;
border: none;
}
/*3e drop*/
/* Dropdown Button */
.dropbtn3 {
font-size: 15px;
font-family: 'Open Sans', sans-serif;
background-color: white;
color: #FB4D4D;
padding: 0px;
margin: 0px;
border: none;
cursor: pointer;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
.dropdown3 {
position: relative;
margin: 5px;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content3 {
display: none;
position: absolute;
background-color: white;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content3 a {
color: #FB4D4D;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content3 a:hover {
background-color: #f1f1f1
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {
display: block;
border: none;
}
button:focus {
outline: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-12 navbar-0">
<div class="col-10 col-container col-center-block navbar-1">
<div class="colom col-3 home"><strong>HOME</strong></div>
<div class="colom col-3 dropdown aanbod">
<button onclick="myFunction()" class="dropbtn">ONS AANBOD</button>
<div id="myDropdown" class="dropdown-content col-12">
WebDesign
Retoucheren
</div>
</div>
<div class="colom col-3 dropdown2 portfolio">
<button onclick="myFunction2()" class="dropbtn2">PORTFOLIO</button>
<div id="myDropdown2" class="dropdown-content2 col-12">
Websites
Retoucheringen
</div>
</div>
<div class="colom col-3 dropdown spelers">
<button onclick="myFunction3()" class="dropbtn3">SPELERS</button>
<div id="myDropdown3" class="dropdown-content3 col-12">
A-Kern
B-Kern
</div>
</div>
<div class="colom col-3 contact"><strong>CONTACT</strong></div>
</div>
</div>
You are calling myFunction3 but not defined you have to create myFunction3 in
js.
function myFunction3() {
document.getElementById("myDropdown3").classList.toggle("show");
}
Appreciate if useful.
Your onClick buttons should be ...
<button onclick="myFunction('myDropdown')" class="dropbtn">ONS AANBOD</button>
<button onclick="myFunction('myDropdown2')" class="dropbtn">PORTFOLIO</button>
<button onclick="myFunction('myDropdown3')" class="dropbtn">SPELERS</button>
... and your function myFunction should look like this:
function myFunction(id) {
document.getElementById(id).classList.toggle("show");
}
I need help with something I'm working on: tabs to show different content. It's simple HTML/CSS with some javascript to help with the tab selection. I have created a simple tab system and I'm able to cycle through all the tabs and show different content. And I'm able to style the active tab with a different color and I use Javascript to change the active tab whenever I click on another tab.
Now for my question, I want to display a little arrow below the active tab. Which just points to the content and shows the active tab. I've tried a few things using the ::before and ::after pseudo classes but I can't get the arrow to stick below the tab headings. For example, I want there to be an arrow below the 'ACADEMICS' or below the 'CHALO LIFE' heading or the 'SPOTLIGHT' heading. If anyone is able to help me do this, I will greatly appreciate.
HTML
<div class="indexContainer grayContainer">
<div class="tabDiv">
<nav class="tab">
<ul class="tabMenu">
<li><a class="tablinks activeTab" onclick=" return openTab(event, 'Academics')" >Academics</a></li>
<li><a class="tablinks" onclick="return openTab(event, 'ChaloLife')">Chalo Life</a></li>
<li><a class="tablinks lastChild" onclick="return openTab(event, 'Spotlight')">Spotlight</a></li>
</ul>
</nav>
<div id="Academics" class="tabContent default">
<h3>Academics</h3>
Talk about our academic programs
</div>
<div id="ChaloLife" class="tabContent">
<h3>Chalo Life</h3>
Talk about life at Chalo Trust School
</div>
<div id="Spotlight" class="tabContent">
<h3>Spotlight</h3>
Spotlight on special events or people
</div>
</div>
</div>
CSS
.indexContainer {
width: 100%;
margin: auto;
min-height: 350px;
height: auto;
}
.grayContainer {
background-color: #ededed;
color: black;
}
nav {
margin: 0px;
}
/*Sets the nav bar in a horizontal manner. Hides the items for the
list and ensures there's no scroll bar*/
nav ul {
display: flex;
flex-direction:row;
margin: 0px;
padding: 0px;
list-style-type: none;
overflow: hidden;
}
/*Styles each of the individual items in the nav bar list. Adds color
and changes their font. Adds a border at the end*/
nav ul li {
flex-grow: 1;
font-family: Constantia,"Lucida Bright",Lucidabright,"Lucida
Serif",Lucida,"DejaVu Serif","Bitstream Vera Serif","Liberation
Serif",Georgia,serif;
font-size: 1em;
font-weight: bolder;
padding: 0;
}
/*Determines how the links inside the navbar will be displayed.Gives
them a background color*/
nav ul li a {
display: block;
background: #800000;
height: 30px;
text-align:center;
padding: 7px 10px;
text-transform: uppercase;
-webkit-transition: 0.45s;
transition: 0.45s;
}
nav.tab {
overflow: hidden;
background: #e4e4e6;
display: block;
margin: auto;
}
nav.tab a {
background-color: inherit;
border: none;
outline: none;
cursor: pointer;
display: block;
margin: auto;
height: 30px;
vertical-align: middle;
padding: 20px 16px;
transition: 0.3s;
border-right: #000 solid 1px;
position: relative;
color: #990000;
}
a.tablinks.lastChild{
border: none;
}
a.tablinks:link {
color: #990000;
font-weight:bolder;
font-size: 20px;
text-transform: capitalize;
}
a.tablinks:visited {
color: #990000;
font-size: 20px;
font-weight: 900;
}
a.tablinks:hover {
color: black;
background: white;
}
ul.tabMenu{
border: none;
display: flex;
flex-direction: row;
}
a.tablinks.activeTab {
background-color: #990000;
color: white;
}
.tabContent {
display: none;
padding: 6px 12px;
border-top: none;
}
.default {
display: block;
}
JAVASCRIPT
function openTab(evt, tabName) {
// Declare all variables
var i, tabContent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabContent = document.getElementsByClassName("tabContent");
for (i = 0; i < tabContent.length; i++) {
tabContent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" activeTab", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(tabName).style.display = "block";
evt.currentTarget.className += " activeTab";
return true;
}
Try this:
function openTab(evt, tabName) {
// Declare all variables
var i, tabContent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabContent = document.getElementsByClassName("tabContent");
for (i = 0; i < tabContent.length; i++) {
tabContent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" activeTab", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(tabName).style.display = "block";
evt.currentTarget.className += " activeTab";
return true;
}
.indexContainer {
width: 100%;
margin: auto;
min-height: 350px;
height: auto;
}
.grayContainer {
background-color: #ededed;
color: black;
}
nav {
margin: 0px;
}
/*Sets the nav bar in a horizontal manner. Hides the items for the
list and ensures there's no scroll bar*/
nav ul {
display: flex;
flex-direction:row;
margin: 0px;
padding: 0px;
list-style-type: none;
overflow: hidden;
}
/*Styles each of the individual items in the nav bar list. Adds color
and changes their font. Adds a border at the end*/
nav ul li {
flex-grow: 1;
font-family: Constantia,"Lucida Bright",Lucidabright,"Lucida
Serif",Lucida,"DejaVu Serif","Bitstream Vera Serif","Liberation
Serif",Georgia,serif;
font-size: 1em;
font-weight: bolder;
padding: 0;
}
/*Determines how the links inside the navbar will be displayed.Gives
them a background color*/
nav ul li a {
display: block;
background: #800000;
height: 30px;
text-align:center;
padding: 7px 10px;
text-transform: uppercase;
-webkit-transition: 0.45s;
transition: 0.45s;
/* ADD THIS */
position: relative;
}
/* ADD THIS */
nav ul li a.activeTab::before {
content: '';
position: absolute;
border: 10px solid transparent;
border-top: 0;
border-bottom-color: black;
position: absolute;
left: 50%;
bottom: 0;
transform: translateX(-50%);
}
/* END ADD */
nav.tab {
overflow: hidden;
background: #e4e4e6;
display: block;
margin: auto;
}
nav.tab a {
background-color: inherit;
border: none;
outline: none;
cursor: pointer;
display: block;
margin: auto;
height: 30px;
vertical-align: middle;
padding: 20px 16px;
transition: 0.3s;
border-right: #000 solid 1px;
position: relative;
color: #990000;
}
a.tablinks.lastChild{
border: none;
}
a.tablinks:link {
color: #990000;
font-weight:bolder;
font-size: 20px;
text-transform: capitalize;
}
a.tablinks:visited {
color: #990000;
font-size: 20px;
font-weight: 900;
}
a.tablinks:hover {
color: black;
background: white;
}
ul.tabMenu{
border: none;
display: flex;
flex-direction: row;
}
a.tablinks.activeTab {
background-color: #990000;
color: white;
}
.tabContent {
display: none;
padding: 6px 12px;
border-top: none;
}
.default {
display: block;
}
<div class="indexContainer grayContainer">
<div class="tabDiv">
<nav class="tab">
<ul class="tabMenu">
<li><a class="tablinks activeTab" onclick=" return openTab(event, 'Academics')" >Academics</a></li>
<li><a class="tablinks" onclick="return openTab(event, 'ChaloLife')">Chalo Life</a></li>
<li><a class="tablinks lastChild" onclick="return openTab(event, 'Spotlight')">Spotlight</a></li>
</ul>
</nav>
<div id="Academics" class="tabContent default">
<h3>Academics</h3>
Talk about our academic programs
</div>
<div id="ChaloLife" class="tabContent">
<h3>Chalo Life</h3>
Talk about life at Chalo Trust School
</div>
<div id="Spotlight" class="tabContent">
<h3>Spotlight</h3>
Spotlight on special events or people
</div>
</div>
</div>
I follow this link to try to make a clickable dropdown menu.
I notice the code from the link is for one dropdown menu and I think this code is for create the dropdown menu.
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Dropdown</button>
<div id="myDropdown" class="dropdown-content">
Home
About
Contact
</div>
</div>
I try to create another two dropdown menus so I copy the code above twice
2nd dropdown
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Dropdown2</button>
<div id="myDropdown" class="dropdown-content">
Home2
About2
Contact2
</div>
</div>
3rd dropdown
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Dropdown3</button>
<div id="myDropdown" class="dropdown-content">
Home2
About2
Contact2
I don't edit anything inside the tag and tag so I click Run on link to see the result.
Only the first dropdown menu (the original one) can show the menu, the other two dropdown menu do not show anything.
I guess the reason is the second dropdown menu and the third dropdown menu do not have proper content inside the and tag.
So I start to modify the code in and tag.
Here is the full code the I added for the second dropdown and the third dropdown menu.
<!DOCTYPE html>
<html>
<head>
<style>
/*1st dropdown*/
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #3e8e41;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
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: #f1f1f1}
.show {display:block;}
/*2nd dropdown*/
.dropbtn2 {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn2:hover, .dropbtn2:focus {
background-color: #3e8e41;
}
.dropdown2 {
position: relative;
display: inline-block;
}
.dropdown-content2 {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content2 a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown2 a:hover {background-color: #f1f1f1}
.show2 {display:block;}
/*3rd dropdown*/
.dropbtn3 {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn3:hover, .dropbtn2:focus {
background-color: #3e8e41;
}
.dropdown3 {
position: relative;
display: inline-block;
}
.dropdown-content3 {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content3 a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown3 a:hover {background-color: #f1f1f1}
.show3 {display:block;}
</style>
</head>
<body>
<h2>Clickable Dropdown</h2>
<p>Click on the button to open the dropdown menu.</p>
1st dropdown
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Dropdown</button>
<div id="myDropdown" class="dropdown-content">
Home
About
Contact
</div>
</div>
2nd dropdown
<div class="dropdown2">
<button onclick="myFunction2()" class="dropbtn2">Dropdown2</button>
<div id="myDropdown2" class="dropdown-content2">
Home2
About2
Contact2
</div>
</div>
3rd dropdown
<div class="dropdown3">
<button onclick="myFunction3()" class="dropbtn3">Dropdown3</button>
<div id="myDropdown3" class="dropdown-content3">
Home3
About3
Contact3
</div>
</div>
<script>
/* 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(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');
}
}
}
}
//for 2nd dropdown
function myFunction2() {
document.getElementById("myDropdown2").classList.toggle("show2");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn2')) {
var dropdowns = document.getElementsByClassName("dropdown-content2");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show2')) {
openDropdown.classList.remove('show2');
}
}
}
}
//for 3rd dropdown
function myFunction3() {
document.getElementById("myDropdown3").classList.toggle("show3");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn3')) {
var dropdowns = document.getElementsByClassName("dropdown-content3");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show3')) {
openDropdown.classList.remove('show3');
}
}
}
}
</script>
</body>
</html>
When I run the code, all buttons can open the dropdown menu when clicked. However, when I click outside of the dropdown menus, only the third button can close the dropdown menu, the first and the second button still open the dropdown menu.
Here are my questions.
Copy another two sets of code for create another two dropdown menu seems not a good practice as the code will become messy, not good for debug and even if there is an update, I have change the code multiple times.
However, if don't copy another two sets of code, the other two dropdown menu will not work.
Even I copy another two sets of code for create another two dropdown menu, I don't understand the dropdown menus do not close when the mouse click outside of them.
Grateful for your advice please. Thank you.
You are overriding three times window.onclick event function. Only the last function launches. If you combine the three functions in one, it works.
Your code now:
<!DOCTYPE html>
<html>
<head>
<style>
/*1st dropdown*/
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #3e8e41;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
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: #f1f1f1}
.show {display:block;}
/*2nd dropdown*/
.dropbtn2 {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn2:hover, .dropbtn2:focus {
background-color: #3e8e41;
}
.dropdown2 {
position: relative;
display: inline-block;
}
.dropdown-content2 {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content2 a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown2 a:hover {background-color: #f1f1f1}
.show2 {display:block;}
/*3rd dropdown*/
.dropbtn3 {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn3:hover, .dropbtn2:focus {
background-color: #3e8e41;
}
.dropdown3 {
position: relative;
display: inline-block;
}
.dropdown-content3 {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content3 a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown3 a:hover {background-color: #f1f1f1}
.show3 {display:block;}
</style>
</head>
<body>
<h2>Clickable Dropdown</h2>
<p>Click on the button to open the dropdown menu.</p>
1st dropdown
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Dropdown</button>
<div id="myDropdown" class="dropdown-content">
Home
About
Contact
</div>
</div>
2nd dropdown
<div class="dropdown2">
<button onclick="myFunction2()" class="dropbtn2">Dropdown2</button>
<div id="myDropdown2" class="dropdown-content2">
Home2
About2
Contact2
</div>
</div>
3rd dropdown
<div class="dropdown3">
<button onclick="myFunction3()" class="dropbtn3">Dropdown3</button>
<div id="myDropdown3" class="dropdown-content3">
Home3
About3
Contact3
</div>
</div>
<script>
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
//for 2nd dropdown
function myFunction2() {
document.getElementById("myDropdown2").classList.toggle("show2");
}
//for 3rd dropdown
function myFunction3() {
document.getElementById("myDropdown3").classList.toggle("show3");
}
// 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');
}
}
}
if (!event.target.matches('.dropbtn2')) {
var dropdowns = document.getElementsByClassName("dropdown-content2");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show2')) {
openDropdown.classList.remove('show2');
}
}
}
if (!event.target.matches('.dropbtn3')) {
var dropdowns = document.getElementsByClassName("dropdown-content3");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show3')) {
openDropdown.classList.remove('show3');
}
}
}
}
</script>
</body>
</html>