Multiple drop-down menus are all linking back to one - javascript

I'm a complete beginner at HTML, CSS, and JS, so forgive me.
Right now this is what I have (sorry for the length and mess):
<!DOCTYPE html>
<html>
<head>
<style>
div.ex1 {
margin: auto;
border: 0px solid transparent;
background-color: transparent;
outline: 0px solid black;
outline-offset: 0px;
width: 800px;
height:
}
div.ex2 {
margin: auto;
border: 0px solid transparent;
background-color: transparent;
outline: 1px dashed #1e58b4;
outline-offset: 25px;
width:680px;
height:
}
div.ex3 {
margin: auto;
border: 0px solid transparent;
background-color: transparent;
outline: 0px dashed #1e58b4;
outline-offset: 25px;
width:730px;
height:
}
</style>
</head>
<style>
.dropbtn {
background-color: #2b89c6;
color: white;
padding: 4px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #2b89c6;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 100%;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
font-size: 12px;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #ddd}
.show {display:block;}
</style>
</head>
<body>
<script>
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');
}
}
}
}
</script>
</body>
<body>
<font face="courier">
<br>
<div class="ex1"><font color="black"><center><font size="2.5pt">============================================================================================<br><font size="6.5pt"><big><font color="#1e58b4">Header Header Header</font></big></font></font></font><br><font color="black"><center><font size="2.5pt">============================================================================================<!--SCIENCE--></font></font><br><div class="dropdown"><button onclick="myFunction()" class="dropbtn"><font face="courier"> Science </font></button><div id="myDropdown" class="dropdown-content">Link 1 Link 2 Link 3 </div></div> <!--ENGLISH--><div class="dropdown"><button onclick="myFunction()" class="dropbtn"><font face="courier"> English </font></button><div id="myDropdown" class="dropdown-content">Link 1 Link 2 Link 3 </div></div> <!--GEOGRAPHY--><div class="dropdown"><button onclick="myFunction()" class="dropbtn"><font face="courier"> Geography </font></button><div id="myDropdown" class="dropdown-content">Link 1 Link 2 Link 3 </div></div> <!--BUSINESS--><div class="dropdown"><button onclick="myFunction()" class="dropbtn"><font face="courier"> Business </font></button><div id="myDropdown" class="dropdown-content">Link 1 Link 2 Link 3 </div></div> <!--FRENCH--><div class="dropdown"><button onclick="myFunction()" class="dropbtn"><font face="courier"> French </font></button><div id="myDropdown" class="dropdown-content">Link 1 Link 2 Link 3 </div></div> <!--MUSIC--><div class="dropdown"><button onclick="myFunction()" class="dropbtn"><font face="courier"> Music </font></button><div id="myDropdown" class="dropdown-content">Link 1 Link 2 Link 3 </div> </div><br><font size="2.5pt">============================================================================================</font></div>
<br>
</font>
When any of the menus are clicked, only the first dropdown comes up. I know there's probably easier ways to do this, but I'd like the appearance to stay exactly as it.
If anyone could show me a fix for this, that'd be beyond helpful.
Thank You!

Your whole document needs revamping to be more up to date in terms of standards and also to make things easier in making it work.
Based on your current document;
Change all of you dropdown divs to be as so.
<div class="dropdown" onclick="myFunction(this)">
<button class="dropbtn"> Science </button>
<div id="myDropdown" class="dropdown-content">Link 1 Link 2 Link 3 </div>
</div>
Change your javascript to be as so;
<script>
function myFunction(element) {
// Here I am assuming the dropdown div to have the same child
// elements in the same order each block
element.children[1].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');
}
}
}
}
</script>
Add font-family: 'Courier New', Courier, monospace into the .dropbtn stylng in order to keep the font. I would advise moving all of the font tags to use this method. You should be using CSS for things like that.
Things to note;
Tags that should not really be used any more;
<font>, <center>, <big>. - These should all be achieved through CSS properties bound to classes and/or IDs.
ID should be set to a unique value for all elements that need it across the current DOM. Class is fine to be used multiple times across elements.

Related

Prototype Pollution script alert doesn't work

This below is my code.
<html>
<head>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://raw.githack.com/alrusdi/jquery-plugin-query-object/9e5871fbb531c5e246aac2aaf056b237bc7cc0a6/jquery.query-object.js"></script>
<style>
.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: 10px;
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;
font-size: small;
}
.dropdown a:hover {background-color: #ddd;}
.show {display: block;}
</style>
</head>
<body>
<h1 id="root"></h1>
<script>
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
var pages = {
home: `HOME </br>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">home</button>
<div id="myDropdown" class="dropdown-content">
about
contact
</div>
</div>`,
about: `ABOUT </br>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">about</button>
<div id="myDropdown" class="dropdown-content">
home
contact
</div>
</div>`,
contact: `CONATCT </br>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">contact</button>
<div id="myDropdown" class="dropdown-content">
home
about
</div>
</div>`
};
var pl = $.query.get('page');
// var pl = new URLSearchParams(window.location.search).get("page");
if (pl == null) {
document.location.search = "?page=home"
}
if(pages[pl] != undefined){
// $('#root').html(pages[pl])
document.getElementById("root").innerHTML = pages[pl];
}else{
document.location.search = "?page=home"
}
</script>
</body>
</html>
And when I try to do a prototype pollution attack on the above code,
example like this,
https://exaple.com?page=hol&__proto__[hol]=<img src=x onerror=alert(1)></img>
it works perfectly and gives an alert popup.
but when I use the script tag it doesn't give me an alert popup,
example like this,
https://exaple.com?page=hol&__proto__[hol]=<script>alert(1)</script>
Can anybody help that what's going on?
why the <img> tag work but not <script> tag?
The version with <script>alert(1)</script> is harmless because HTML5 specifies that a <script> tag inserted with innerHTML should not execute.
See mdn on innerHTML - Security considerations.

javascript Dropdown menu always opens at a specific location

i have a javaScript Drop Down menu which i'am displaying in table row along with some other data . so when i click on the first menu button it opens like it should , slightly below the button , but when i press the menu button for the other rows of data below i the menu always opens in the position of the first row of the table .
long story short i click the dropdown menu and menu appears somewhere else away from the button .
my javascript
/* click on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown
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');
}
}
}
}
the CSS
.dropbtn {
background-color: #027581;
color: white;
padding: 3.5px;
font-size: 16px;
border: none;
cursor: pointer;
border-radius: 10%;}
.dropbtn:hover, .dropbtn:focus {
background-color: #2980B9; }
.dropdown {
position:relative;
display:flex;
text-align: left; }
.dropdown-content {
display: none;
position:absolute;
background-color: #f1f1f1;
max-width: 150px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1; }
show {display:block;}
the html
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Action ▼</button>
<div id="myDropdown" class="dropdown-content">
View
Delete
any help i appreaciated
On the .dropdown-content you are displaying it as absolute without giving it any position, so it will be at 0,0 of the first parent that is not position:static, so in this case the div.dropdown. Where you are using flex-box on that div, you can utilize flex-direction: column to flow the elements in a column.
EDIT:
In a table situation, the event function is calling an ID. Since an ID needs to be unique, and you are assigning multiple elements with the same ID, the function is only finding the first element with that ID and toggling the class of that element. So in your case it will always be the first row.
In the snippet below, I adjusted it to be a table. In the event function, I pass the event. I can then get the event.target which is the "button" that was clicked. By adding on .parentNode to the end of that (event.target.parentNode), it will go up the DOM one level, and get the parent of the clicked on button. You can use the querySelector on that div to find just the div.dropdown-content within that parent div and toggle the .show class.
See if the snippet below is what you are looking for.
/* click on the button,
toggle between hiding and showing the dropdown content */
function myFunction(event) {
const parent = event.target.parentNode;
parent.querySelector(`.dropdown-content`).classList.toggle(`show`)
}
// Close the dropdown
window.onclick = function(event) {
if (!event.target.matches(`.dropbtn`)) {
document.querySelectorAll(`.dropdown-content.show`)
.forEach(element => element.classList.remove(`show`));
}
}
* {
border-collapse: collapse;
}
td {
border: 1px solid black;
padding: 1rem;
}
td:first-child {
padding: 0 1rem;
}
.dropbtn {
background-color: #027581;
color: white;
padding: 3.5px;
font-size: 16px;
border: none;
cursor: pointer;
border-radius: 10%;
}
.dropbtn:hover,
.dropbtn:focus {
background-color: #2980B9;
}
.dropdown {
position: relative;
display: flex;
text-align: left;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
max-width: 150px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.show {
display: block;
}
<table>
<tbody>
<tr>
<td>
<div class="dropdown">
<button onclick="myFunction(event)" class="dropbtn">Action ▼</button>
<div class="dropdown-content">
View
Delete
</div>
</div>
</td>
<td>Row 1 / Column 2</td>
<td>Row 1 / Column 3</td>
<td>Row 1 / Column 4</td>
</tr>
<tr>
<td>
<div class="dropdown">
<button onclick="myFunction(event)" class="dropbtn">Action ▼</button>
<div class="dropdown-content">
View
Delete
</div>
</div>
</td>
<td>Row 2 / Column 2</td>
<td>Row 2 / Column 3</td>
<td>Row 2 / Column 4</td>
</tr>
</tbody>
</table>

Removing Class Using Javascript

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>

How to hide the other dropdown when others is selected

I have a menubar with 2 options which shows dropdowns on click, technically theyre all shown even you click only one. All I wanted to do is to hide other dropdowns after when I click other menu items.
What is wrong with my code?
BODY:
<body>
<ul>
<li class="File">
File
<div class="dropdown-content" id="myDropdown">
Open
Save
Save As
Close
</div>
<li class="Edit">
Edit
<div class="dropdown-content" id="myDropdown2">
Undo
Redo
Cut
Copy
Paste
</div>
</li>
</ul>
<div id="TITLE" style="font-family: verdana; font-size: 36px; margin-left: 1200px; margin-top: -45px; color: white;">
PANTS
</div>
<!-- THE FUNCTION FOR CLICK -->
<script>
var drptochoose;
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
document.getElementById("myDropdown2").classList.toggle("show");
}
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
for (var d = 0; d < dropdowns.length; d++) {
var openDropdown = dropdowns[d];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
</script>
<!-- END OF FUNCTION FOR CLICK -->
</body>
CSS:
<style>
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: green;
font-family: verdana;
font-size: 14px;
}
li {
float: left;
}
li a, .dropbtn {
display: inline-block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover, .dropdown:hover .dropbtn {
background-color: red;
}
li.dropdown {
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
.dropdown-content a:hover {background-color: #f1f1f1}
.show {display:block;}
<script src="jquery.js"></script>
</style>
The problem with your code is that it toggles both dropdowns. Therefore, when they are both not shown they get this class.
You can do something like this:
<body>
<ul>
<li class="File">
File
<div class="dropdown-content" id="myDropdown">
Open
Save
Save As
Close
</div>
</li>
<li class="Edit">
Edit
<div class="dropdown-content" id="myDropdown2">
Undo
Redo
Cut
Copy
Paste
</div>
</li>
</ul>
<div id="TITLE" style="font-family: verdana; font-size: 36px; margin-left: 1200px; margin-top: -45px; color: white;">
PANTS
</div>
<!-- THE FUNCTION FOR CLICK -->
<script>
var drptochoose;
function hideDropdowns(excludeId) {
var dropdowns = document.getElementsByClassName("dropdown-content");
for (var d = 0; d < dropdowns.length; d++) {
var openDropdown = dropdowns[d];
if (openDropdown.classList.contains('show') && excludeId !== openDropdown.id) {
openDropdown.classList.remove('show');
}
}
}
function myFunction(id) {
id.classList.toggle("show");
hideDropdowns(id.id);
}
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
hideDropdowns();
}
}
</script>
<!-- END OF FUNCTION FOR CLICK -->
</body>
You need something like this
jsFiddleDemoNavBar
I dont think you need to go through all that code to do what your looking for as i understand it. Just use a .hide class to hide the dropdowns by default on page load and then toggle them using the button onclick with call(this) and nextElementSibling.
Here is the code.
<style>
.hide{
display:none;
}
</style>
<body>
<ul>
<li class="File">
File
<div class="dropdown-content hide" id="myDropdown">
Open
Save
Save As
Close
</div>
</li>
<li class="Edit">
Edit
<div class="dropdown-content hide" id="myDropdown2">
Undo
Redo
Cut
Copy
Paste
</div>
</li>
</ul>
<div id="TITLE" style="font-family: verdana; font-size: 36px; margin-left: 1200px; margin-top: -45px; color: white;">
PANTS
</div>
<script>
var drptochoose;
function myFunction() {
var isAlreadyOpen = false;
if(!this.nextElementSibling.classList.contains('hide'))
{
// if the clicked button dropdown is already open then use this bool to not show it again.
isAlreadyOpen = true;
}
var dropdowns = document.getElementsByClassName("dropdown-content");
for (var d = 0; d < dropdowns.length; d++) {
var openDropdown = dropdowns[d];
if (!openDropdown.classList.contains('hide')) {
openDropdown.classList.toggle("hide");
}
}
if(!isAlreadyOpen)
{
// if the dropdown was hidden when clicked then show it
this.nextElementSibling.classList.toggle("hide");
}
}
</script>
</body>
Hope this helps.
window.onclick = function(e) {
if (e.target.matches('.dropbtn')) {
var allDropDown = document.querySelectorAll('.dropdown-content');
//This will hide all the dropdown for everytime you click
[].forEach.call(allDropdown, function(dropdown){
dropdown.classList.add('hide');
});
//This will show the subdrop down of that menu
var dropdown = e.target.parent.querySelector(".dropdown-content");
dropdown.classList.add('show');
}
}
}

Improve javascript code for drop down menu

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>

Categories

Resources