I'm not to familiar with JavaScript and I was hoping to get a little help with a problem I can't seem to fix. I currently have 2 Drop Down Menus on my website. One is a drop down menu for the navigation which is activated when clicking a hamburger menu icon. The second drop down is being used to show categories on my website. Currently when I click one drop down, I have to click it again in order to close it. If I click the second drop down without closing the first both will remain visible. What I would like to happen is two things. First I would like it so that if a user clicks anywhere outside of the div for the drop down menu it automatically closes. The second thing I would like to see happen is only have one drop down menu visible at a time. So if I click one and another drop down is open I want it to be closed. Hopefully I explained this well. Now onto the code I'm using.
The following is within my head.
<script>
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function DropDownMenuNavigation() {
document.getElementById("b2DropDownMenuNav").classList.toggle("show");
}
function DropDownMenuCategory() {
document.getElementById("b2DropDownMenuCat").classList.toggle("show");
}
</script>
Then I use this as the button to activate the navigation drop down menu. This is included within my body.
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuNavigation()" class="dropbtn">☰ MENU</button>
</div>
and this what I use to include my category drop down menu.
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuCategory()" class="dropbtn">CATEGORIES</button>
</div>
Now lastly is the css I use just on the off chance that helps any.
/* Dropdown Button */
.dropbtn {
background-color: #0066a2;
color: white;
padding: 1px;
font-size: 15px;
font-weight: bold;
border: none;
cursor: pointer;
}
.dropbtn a {
color: #FFFFFF;
text-decoration: none;
font-size: 15px;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
float: left;
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #0066a2;
min-width: 260px;
max-width: 960px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: #000000;
text-decoration: none;
}
/* 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;}
So what would be the best method to go about doing what I'm asking? Could someone maybe lend me a hand and point me in the right direction. Thanks a lot and I appreciate any help you could lend me.
The onclick attribute shouldn’t include the (). It should look like this:
<button onclick="DropDownMenuNavigation" class="dropbtn">☰ MENU</button>
Or—even better—don’t put the event listener inline, put it in the script.
Also, remove the “show” class from the other dropdown when the button is pressed.
See here:
document.getElementById('menudropbtn').addEventListener('click', function () {
document.getElementById('b2DropDownMenuNav').classList.toggle('show')
document.getElementById('b2DropDownMenuCat').classList.remove('show')
})
document.getElementById('categoriesdropbtn').addEventListener('click', function () {
document.getElementById('b2DropDownMenuCat').classList.toggle('show')
document.getElementById('b2DropDownMenuNav').classList.remove('show')
})
/* Dropdown Button */
.dropbtn {
background-color: #0066a2;
color: white;
padding: 1px;
font-size: 15px;
font-weight: bold;
border: none;
cursor: pointer;
}
.dropbtn a {
color: #FFFFFF;
text-decoration: none;
font-size: 15px;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
float: left;
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #0066a2;
min-width: 260px;
max-width: 960px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: #000000;
text-decoration: none;
}
/* 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;
}
<div class="dropbtn" style="float: left;">
<button class="dropbtn" id="menudropbtn">☰ MENU</button>
<div class="dropdown">
<div class="dropdown-content" id="b2DropDownMenuNav">
<a>Something</a>
</div>
</div>
</div>
<div class="dropbtn" style="float: left;">
<button class="dropbtn" id="categoriesdropbtn">CATEGORIES</button>
<div class="dropdown">
<div class="dropdown-content" id="b2DropDownMenuCat">
<a>Something else</a>
</div>
</div>
</div>
To do this, you can add custom JS functions that will open dropdowns based on element ID, and when one dropdown is opened, all others will be closed. You can create a function that closes all the dropdowns. Then, in your "open" function, call the "close_all" function first.
Here's a working snippet.
// Functions for Interactive File Menu Bar
// - Click Butoon to Open Dropdown
// - Clicking one dropdown closes all other
// - Clicking outside the file menu bar will close all the dropdown.
function open_dropdown(element_id) {
console.log('Opening Dropdown:', element_id)
close_all_dropdowns()
document.getElementById(element_id).style.display = 'block';
}
// Close the dropdown if the user clicks outside of it
function close_dropdown(element) {
console.log('I am closing dropdown:', element)
element.style.display = 'none'
}
// Close all dropdowns.
function close_all_dropdowns() {
var dropdowns = document.getElementsByClassName('dropdown-content')
for (var i = 0; i < dropdowns.length; i++) {
close_dropdown(dropdowns[i]);
}
}
// Close all dropdowns when clicking outside.
window.onclick = function (e) {
if (!e.target.matches('.dropbtn')) {
close_all_dropdowns()
}
}
/* Styles for the File Menu Bar. */
.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: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://unpkg.com/98.css">
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
<title>RetroNet</title>
</head>
<body>
<div class="window" style="width: 100%">
<div class="title-bar">
<div class="title-bar-text">Welcome to RetroNet!</div>
<div class="title-bar-controls">
<button aria-label="Minimize"></button>
<button aria-label="Maximize"></button>
<button aria-label="Close"></button>
</div>
</div>
<!-- Main menu -->
<div class="window-body">
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_file')">File</button>
<div class="dropdown-content" id="dd_file">
Open
Close
Settings
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_edit')">Edit</button>
<div class="dropdown-content" id="dd_edit">
Cut
Copy
Paste
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_view')">View</button>
<div class="dropdown-content" id="dd_view">
Toggle CSS
Toggle Javascript
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_tools')">Tools</button>
<div class="dropdown-content" id="dd_tools">
Not Decided
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_favorite')">Favourties</button>
<div class="dropdown-content" id="dd_favorite">
Add New Favorite
Add this Page to Favorites
Show Favorites
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_help')">Help</button>
<div class="dropdown-content" id="dd_help">
README
</div>
</div>
</div>
</div>
</body>
</html>
Maybe the following code can help. You can use custom event to have module items (like menu, popup or such) communicate to each other.
If a menu button is clicked then you can dispatch a custom event. Any other item on the page may do something according to what this event is (like pausing a game when a main menu is opened).
// find menu-content in item (=menu-button) and return
// "none" if menu-content.style.display is "block"
// "block" if menu-content.style.display is not "block"
const toggle =
(item) => {
const content =
item.querySelector("[x-role=\"menu-content\"]");
return content.style.display === "block"
? "none"
: "block"
}
;
// set menu-content found in item (=menu-button) to
// none or block
const changeDisplay =
(item,display) =>
item.querySelector("[x-role=\"menu-content\"]")
.style.display = display;
// when menu-button is clicked
const menuButtonClicked =
e => {
//get the toggled content style
// if current style is block then
// toggled is none and vice versa
const style = toggle(e.target);
//hide all menus, in the for each we
// added an event listener for "menu-click" event
// the listener will hide the menu
var evt = new Event("menu-click",{});
document.body.dispatchEvent(evt);
//set style of the current
changeDisplay(e.target,style);
}
;
//for each menu-botton role
// I am not using css selectors on class, class is for style,
// user defined properties can be used for behavior.
// If you mix this up then you can break style, behavior
// or both when changing behavior or style
document.querySelectorAll("[x-role=\"menu-button\"]")
.forEach(
x => {
//when clicked let menuButtonClicked handle it
x.addEventListener(
"click"
,menuButtonClicked
);
//listen to custom event called "menu-click"
// set display to none when this happens
// if you were to dynamically add and remove
// menu items then you should remove the event
// listeners when you remove the menu
document.body.addEventListener(
"menu-click"
,e => changeDisplay(x,"none")
);
}
)
;
.menu-button {
cursor: pointer;
}
.menu-content {
display:none;
}
<div class="menu-button" x-role="menu-button">
menu1
<div class="menu-content" x-role="menu-content">
<ul>
<li>one</li>
<li>two</li>
</ul>
</div>
</div>
<div class="menu-button" x-role="menu-button">
menu2
<div class="menu-content" x-role="menu-content">
<ul>
<li>three</li>
<li>four</li>
</ul>
</div>
</div>
<div class="menu-button" x-role="menu-button">
menu3
<div class="menu-content" x-role="menu-content">
<ul>
<li>five</li>
<li>six</li>
</ul>
</div>
</div>
Related
I have adapted some code from the W3 hoverable dropdown tutorial and want to make it so that rather than following a link when clicked, it passes a value to a function. A rough snippet of the HTML code is below:
<div class="dropdown">
<button class="dropbtn">Item</button>
<div class="dropdown-content" (change)="selectChange($event)">
<a value="egg">Egg</a>
<a value="milk">Milk</a>
</div>
</div>
I want to figure out how to get the value "egg" into the JavaScript function selectChange if the user clicks on that box, but currently, the boxes are not clickable and don't do anything. I would like to avoid using a <select> tag if possible.
Here is the W3 link I got the structure of this code from:
https://www.w3schools.com/howto/howto_css_dropdown.asp
You've tagged this with angular, so I'm assuming you're using that framework. If that's the case, just use (click)="function()".
<div class="dropdown">
<button class="dropbtn">Item</button>
<div class="dropdown-content">
<a (click)="selectChange('egg')">Egg</a>
<a (click)="selectChange('milk')">Milk</a>
</div>
</div>
Probably the best solution
How about an eventListener to all the links in the dropdown in Javascript that checks if when a link was clicked and then performs the function with the value of the element that was clicked?
Probably the easiest solution
Or maybe for just a few elements or if you don't feel like/don't know how to use an eventListener for this could always use some simple onclick events with a parameter.
function selectChange(selected)
{
//not sure what you want to do now
console.log(selected);
alert(selected);
}
.dropbtn {
background-color: #04AA6D;
color: white;
padding: 16px;
font-size: 16px;
border: none;
}
.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: 1;
}
.dropdown-content span {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content span:hover {background-color: #ddd;}
.dropdown:hover .dropdown-content {display: block;}
.dropdown:hover .dropbtn {background-color: #3e8e41;}
<div class="dropdown">
<button class="dropbtn">Item</button>
<div class="dropdown-content">
<span onclick="selectChange('egg')">Egg</span>
<span onclick="selectChange('milk')">Milk</span>
</div>
</div>
*In this example a replaced the a-tags with span as you probably shouldn't use an anchor-tag without a href.
I am looking for some (probably easy) advice which I cant seem to find googling. I have a hoverable dropdown menu such as:
/* Dropdown Button */
.btn {
background-color: #D6182D;
color: white;
padding: 8px;
font-size: 16px;
border: none;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
display: inline-block;
border: 10px;
}
/* Dropdown Content (Hidden by Default) */
.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: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content a:hover {
background-color: #ddd;
}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
}
/* Change the background color of the dropdown button when the dropdown content is shown */
.dropdown:hover .btn {
background-color: rgb(134, 30, 42);
}
<center>
<div class="dropdown">
<a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Chose a month to display</a>
<div class="dropdown-content">
<a class="nav-link" href="/jan">
<font color="black">January 2018</font>
</a>
<a class="nav-link" href="/feb">
<font color="black">February 2018</font>
</a>
<a class="nav-link" href="/mar">
<font color="black">March 2018</font>
</a>
<a class="nav-link" href="/tot">
<font color="black">Total</font>
</a>
</div>
</div>
</center>
Basically taken from w3schools..
Now instead of "Chose a month to display" I would like to display the chosen option once someone clicks on it. Do you guys have any idea on how to change the code to do so?
Looking forward to your answers :-)
I made some changes in your HTML to make it more semantic and for dropdown text, you can try plain javascript. I hope, This will help you.
For old value, you can store your value somewhere, like in localstorage
For Example, I am saving old selected value in local storage.
const months = document.getElementsByClassName("dropdown-content");
if(localStorage.getItem("oldval")){
document.getElementById("dropdownMenuLink").innerHTML =
localStorage.getItem("oldval");
}
Array.from(months).map(month=>{
month.addEventListener("click",(e)=>{
let selectedValue = e.target.textContent;
document.getElementById("dropdownMenuLink").innerHTML =
selectedValue;
localStorage.setItem("oldval",selectedValue);
});
});
const months = document.getElementsByClassName("dropdown-content");
Array.from(months).map(month=>{
month.addEventListener("click",(e)=>{
e.preventDefault();
let selectedValue = e.target.textContent;
document.getElementById("dropdownMenuLink").innerHTML = selectedValue;
});
});
/* Dropdown Button */
.btn {
background-color: #D6182D;
color: white;
padding: 8px;
font-size: 16px;
border: none;
min-width: 200px;
display:inline-block;
text-decoration:none;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
display: inline-block;
border: 10px;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 200px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
list-style: none;
padding:0;
margin:0;
}
/* Links inside the dropdown */
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content a:hover {
background-color: #ddd;
}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
}
/* Change the background color of the dropdown button when the dropdown content is shown */
.dropdown:hover .btn {
background-color: rgb(134, 30, 42);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<center>
<div class="dropdown">
<a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Chose a month to display</a>
<ul class="dropdown-content">
<li><a class="nav-link" href="/jan">
January 2018
</a></li>
<li><a class="nav-link" href="/feb">
February 2018
</a></li>
<li><a class="nav-link" href="/mar">
March 2018
</a></li>
<li><a class="nav-link" href="/tot">
Total
</a></li>
</ul>
</div>
</center>
</body>
</html>
as i can see you are using <div> and <a> to achieve a drop-down which is not wrong at all but is not correct way of html to do it.
Read about <select> and <option> tag which will help you to get a drop-down effect as well as you can set value inside <option> tag dynamically as you click it. by using getElementById('id-of-element')
read about getElementById here
Also if you want some redirection when user clicks it you can use <a> tag inside <option> tag.
select tag
hope this will help you, post any doubts if you have will be happy to help you :-)
I'm trying to teach myself a little javascript for project I am working on and just wanted to see if I could get some help. I use 3 different drop down menus and I use the below function to hide one menu when another is clicked. It worked
function DropDownMenuNavigation() {
document.getElementById("DropDownMenuNav").classList.toggle("show");
document.getElementById('DropDownMenuChart').classList.remove('show');
}
The above code worked well when I had 2 different drop down menus. But now that I have 3 it doesn't seem to see the 3 line I've added below.
function DropDownMenuNavigation() {
document.getElementById("DropDownMenuNav").classList.toggle("show");
document.getElementById('DropDownMenuChart').classList.remove('show');
document.getElementById('DropDownMenuCat').classList.remove('show');
}
If I switch the bottom line with the middle line it will regonize that line, I'm guessing there is something wrong with the format I'm writing it in? Something tells me I'm not including a separator or something. Anyways, I know its something small, maybe someone could point it out to me.
EDIT:
JAVASCRIPT
<script>
function DropDownMenuNavigation() {
document.getElementById("b2DropDownMenuNav").classList.toggle("show");
document.getElementById("b2DropDownMenuCat").classList.toggle("remove");
document.getElementById("b2DropDownMenuCha").classList.toggle("remove");
}
function DropDownMenuCategory() {
document.getElementById("b2DropDownMenuCat").classList.toggle("show");
document.getElementById("b2DropDownMenuNav").classList.toggle("remove");
}
function DropDownMenuCharts() {
document.getElementById("b2DropDownMenuCha").classList.toggle("show");
document.getElementById("b2DropDownMenuNav").classList.toggle("remove");
}
</script>
HTML
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuNavigation()" class="dropbtn">☰ MENU</button>
</div>
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuCategory()" class="dropbtn">CATEGORIES</button>
</div>
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuCharts()" class="dropbtn">CATEGORIES</button>
</div>
<div class="dropdown">
<div id="b2DropDownMenuCategory" class="dropdown-content">
1
</div>
</div>
<div class="dropdown">
<div id="b2DropDownMenuCharts" class="dropdown-content">
2
</div>
</div>
<div class="dropdown">
<div id="b2DropDownMenuNavigation" class="dropdown-content">
3
</div>
</div>
CSS
/* Dropdown Button */
.dropbtn {
background-color: #0066a2;
color: white;
padding: 1px;
font-size: 15px;
font-weight: bold;
border: none;
cursor: pointer;
}
.dropbtn a {
color: #FFFFFF;
text-decoration: none;
font-size: 15px;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
float: left;
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #0066a2;
min-width: 260px;
max-width: 960px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: #000000;
text-decoration: none;
}
/* 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;}
The code you posted has mismatches between the actual ids of the content and the document.getElementById() lines, but assuming that you correct that, your code does in fact work, but each bit of content just winds up going under the other, so you never see the correct content.
function DropDownMenuNavigation() {
document.getElementById("b2DropDownMenuNav").classList.toggle("show");
document.getElementById("b2DropDownMenuCat").classList.toggle("remove");
document.getElementById("b2DropDownMenuCha").classList.toggle("remove");
}
function DropDownMenuCategory() {
document.getElementById("b2DropDownMenuCat").classList.toggle("show");
document.getElementById("b2DropDownMenuNav").classList.toggle("remove");
}
function DropDownMenuCharts() {
document.getElementById("b2DropDownMenuCha").classList.toggle("show");
document.getElementById("b2DropDownMenuNav").classList.toggle("remove");
}
/* Dropdown Button */
.dropbtn {
background-color: #0066a2;
color: white;
padding: 1px;
font-size: 15px;
font-weight: bold;
border: none;
cursor: pointer;
}
.dropbtn a {
color: #FFFFFF;
text-decoration: none;
font-size: 15px;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
float: left;
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #0066a2;
min-width: 260px;
max-width: 960px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: #000000;
text-decoration: none;
}
/* 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;}
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuNavigation()" class="dropbtn">☰ MENU</button>
</div>
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuCategory()" class="dropbtn">CATEGORIES</button>
</div>
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuCharts()" class="dropbtn">CATEGORIES</button>
</div>
<div class="dropdown">
<div id="b2DropDownMenuCat" class="dropdown-content">
1
</div>
</div>
<div class="dropdown">
<div id="b2DropDownMenuCha" class="dropdown-content">
2
</div>
</div>
<div class="dropdown">
<div id="b2DropDownMenuNav" class="dropdown-content">
3
</div>
</div>
But, since you are new to this, it's best not to start off with bad habits, so don't use inline HTML event attributes (i.e. onclick, etc.), there are many reasons why and you can review them here.
Next, you have a lot of unneeded HTML and the structure of the HTML should be altered to represent the hierarchy of the content.
Also, you don't need separate functions for each menu click as trying to keep track of what should be hidden and what should be shown in an ever-increasing list of menu items is not a scaleable result.
When these changes are made, the HTML is much cleaner and less involved and the JavaScript is also much simpler:
// First, get references to the HTML elements your code will need.
// You could get individual references, like this:
/*
var b2DropDownMenuNav = document.getElementById("b2DropDownMenuNav");
var b2DropDownMenuCat = document.getElementById("b2DropDownMenuCat");
var b2DropDownMenuCha = document.getElementById("b2DropDownMenuCha");
*/
// But in your case, a single reference to the collection of menus will do.
// We'll also want that collection to be converted to a JavaScript array.
var menus = Array.prototype.slice.call(document.querySelectorAll(".dropbtn"));
// Now, we can just loop over the array and give the buttons a common function
// to perform when they are clicked (no need for multiple functions.
menus.forEach(function(menu){
menu.addEventListener("click", function(){
// Hide any currently showing menu content
Array.prototype.slice.call(document.querySelectorAll(".dropdown-content")).forEach(function(content){
content.classList.remove("show");
});
// Show the content of the menu that was clicked:
menu.querySelector(".dropdown-content").classList.toggle("show");
});
});
/* Dropdown Button */
.dropbtn {
background-color: #0066a2;
color: white;
padding: 1px;
font-size: 15px;
font-weight: bold;
border: none;
cursor: pointer;
float:left; /* no need to write this inline with the HTML, just put it here */
}
.dropbtn a {
color: #FFFFFF;
text-decoration: none;
font-size: 15px;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
/* I can't see any need for this class at all:
.dropdown {
float: left;
position: relative;
display: inline-block;
}
*/
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
background-color: #0066a2;
min-width: 260px;
max-width: 960px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
position: absolute;
/* z-index: 1; <-- NOT NEEDED */
}
/* Links inside the dropdown */
.dropdown-content a {
color: #000000;
text-decoration: none;
}
/* 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; }
<!-- There is no need to nest button elements inside of div elements.
Just get rid of the buttons completely and make the divs the clickable
elements. -->
<div class="dropbtn" id="b2DropDownMenuNav">☰ MENU
<div class="dropdown dropdown-content">1</div>
</div>
<div class="dropbtn" id="b2DropDownMenuCat">CATEGORIES
<div class="dropdown dropdown-content">2</div>
</div>
<div class="dropbtn" id="b2DropDownMenuCha">CATEGORIES
<div class="dropdown dropdown-content">3</div>
</div>
I have a navigation bar with a dropdown menu (on hover). I would like the dropdown menu items to have the same size as the parent.
Here is a picture:
So I would now like "One" & "Two" to have the exact same size as "This is a dropdown" (at least in terms of width). Right now they are a little bit too big. When I resize the window, the parent element ("This is a dropdown") changes size, and "One" & "Two" should then resize accordingly, as it were.
Code
I have a navbar with different elements which is basically structured like this:
<div class="container-fluid nopadding navbar"> <!-- NAVBAR -->
<div class="row">
<div class="container-fluid col-xs-12 col-sm-12 col-md-10"> <!-- MENU -->
<div class="row">
<div class="dropdown col-xs-12 col-sm-2">
<div class="container-fluid">
<div class="row">
<button class="dropbtn col-xs-12">This is a dropdown</button>
<div class="dropdown-content col-xs-12 nopadding">
One
Two
</div>
</div>
</div>
</div>
...more navbar elements follow here
</div>
</div>
</div>
</div>
Here's some of the CSS:
/* Dropdown Button */
.dropbtn {
background-color: #F6F8FB;
border: none;
cursor: pointer;
font-family: AlegreyaSansSC-Light;
font-size: 16px;
color: #637F92;
letter-spacing: 0.52px;
height: 81px;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #F6F8FB;
z-index: 1;
}
/* Change color of dropdown links on hover */
.dropdown-content a:hover {
background: rgb(221, 232, 241); /* Fallback for older browsers without RGBA-support */
background: rgba(221, 232, 241, 0.95);
}
/* Links inside the dropdown */
.dropdown-content a {
padding: 30px;
text-align: center;
text-decoration: none;
display: block;
}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
top: 81px;
position: absolute;
}
I have rather included a little bit too much here, just to be sure.
You should remove the padding from the .dropdown-content a element:
.dropdown-content a {
/*padding: 30px;*/
text-align: center;
text-decoration: none;
display: block;
}
Try adding width: 100%; in your .dropbtn and .dropdown:hover .dropdown-content. This should set all elements to parent width.
The below code has two drop down menus which load container on button click and drop down closes on clicking anywhere on page. Though the window load works but the pages inside takes too much time to load even on local server obviously because my javascript code isn't the way it should. So guys what should my javascript code like so that it loads page correctly and at the same time closes drop down on clicking anywhere on page [if both drop downs are open both should close on click like in snippet].
function myFunction(event) {
event.stopPropagation();
document.getElementById("myDropdown").classList.toggle("show");
}
function myFunction2(event) {
event.stopPropagation();
document.getElementById("myDropdown2").classList.toggle("show");
}
window.onclick = function(event) {
$("#notificationContainer").load("notifications.php");
document.getElementById("myDropdown").classList.remove("show");
$("#scoreContainer").load("score.php");
document.getElementById("myDropdown2").classList.remove("show");
}
.dropdown,
.dropdown2 {
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content,
.dropdown-content2 {
display: none;
background-color: #fff;
position: absolute;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
right: 0;
}
.dropdown-content a,
.dropdown-content2 a {
padding: 10px 16px;
text-decoration: none;
display: block;
}
.show {
display: block;
}
.dropbtn {
height: 25px;
width: 50px;
border: none;
background-color: white;
background: red;
}
.dropbtn2 {
height: 25px;
width: 50px;
border: none;
background-color: white;
background: green;
}
.dropdown-content,
.dropdown-content2 {
border: 2px solid #c6c6c6;
border-top: none;
}
#notificationContainer,
#scoreContainer {
min-width: 400px;
min-height: 100px;
border: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tr>
<td style="padding-right:15px;">
</td>
<td style="padding-right:15px;">
<div class="dropdown2">
<button onclick="myFunction2(event)" class="dropbtn2">one</button>
<div id="myDropdown2" class="dropdown-content2">
<div id="scoreContainer"></div>
</div>
</div>
</td>
<td style="padding-right:15px;">
<div class="dropdown">
<button onclick="myFunction(event)" class="dropbtn">two</button>
<div id="myDropdown" class="dropdown-content">
<div id="notificationContainer"></div>
</div>
</div>
</td>
</tr>
</table>
The above javascript is modified from the below single drop down menu code which loaded the page inside container instantly, but my modified version [above] takes too much time:
<script type="text/javascript">
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function(event) {
$( "#notificationContainer" ).load( "notifications.php" );
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');
}
}
}
}
</script>
there is nothing inherently wrong or slow about your javascript code. have you tried inspecting how long your PHP code runs? because that's where I would start looking for the problem.
There is nothing wrong with your dropdowns. They work fine. But they lack in design and the code looks way too much for such small control. I suggest you use Bootstrap. CSS and Javascript codes are external and you just need to place your dropdown in your project by coding some HTML.
There are several different designs and the way it works simpler than what you coded. Take a look at the below example and this page for more info about it:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h2>Bootstrap Dropdown Example</h2>
<p>Nice design, easy usage, good performance.</p>
<p><b>To open the dropdown menu, use a button or a link with a class of .dropdown-toggle and data-toggle="dropdown".</b></p>
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li>THIS</li>
<li>IS</li>
<li>A DROPDOWN</li>
</ul>
</div>
</div>
</body>
</html>