Is it possible to move to next element in my DIV wih E and return to previous element with A. I'm trying to make a menu and navigate within only with keys.
// Add active class to the current button (highlight it)
var header = document.getElementById("myDIV");
var btns = header.getElementsByClassName("btn1");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
var current = document.getElementsByClassName("active");
if (current.length > 0) {
current[0].className = current[0].className.replace(" active", "");
}
this.className += " active";
});
}
/* Mini menu CSS */
/* Style the buttons */
#myDIV{
margin-top:50px;
margin-left: 12px;
margin-right: px;
display:inline-flex;
}
#myDIV btn1{
top:3px;
}
#myDIV p{
top:4px;
/*margin-left: 10px;*/
letter-spacing: 1.8px;
}
.btn1 {
border: none;
outline: none;
padding: 3px 12px;
cursor: pointer;
font-size: 18px;
border-radius: 2rem;
transition: 0.2s;
position: relative;
text-align: center;
align-items: center;
justify-content: center;
overflow: visible;
color: #000;
font-family: Proxima Nova;
font-weight: bold;
}
.active {
border-color: #366eaf;
border-width: 2px;
border-style: solid;
}
<div id="myDIV" style="display: inline-flex; margin-left: 15px; margin-right: 5px;">
<p class="btn1 active">ALL</p>
<p class="btn1">MENU1</p>
<p class="btn1">MENU2</p>
<p class="btn1">MENU3</p>
<p class="btn1">MENU4</p>
<p class="btn1">MENU5</p>
</div>
Semantically, you should be using an unordered list (<ul>) since you are actually making a list of menu items.
Next, it really isn't a "move" that you want, but a change of which element has the active class applied to it.
Your original JavaScript (while working) is more than you needed to be doing. See my reworked version with comments.
Lastly, you had some errors and some redundancy in your CSS.
See the comments inline for details.
// Listen for key strokes on the document
document.addEventListener("keydown", function(event){
// Get the currently active element
let activeElement = document.querySelector(".active");
// Check for "e" and if there is a previous sibling
if(event.key == "a" && activeElement.previousElementSibling){
// Make the previous sibling (if any) element active
deselectAll();
activeElement.previousElementSibling.classList.add("active");
} else if(event.key == "e" && activeElement.nextElementSibling){
// Make the next sibling element (if any) active
deselectAll();
activeElement.nextElementSibling.classList.add("active");
}
});
// Just set up one event handler on the parent of all the menu items
// Any click within that parent will bubble up and be handled here
document.getElementById("menu").addEventListener("click", function(event) {
// event.target is the actual element that triggered the event
if(event.target.classList.contains("btn1")){
deselectAll();
event.target.classList.add("active"); // Add active to the clicked item
}
});
// Don't use .getElementsByClassName() - - it's outdated
let items = document.querySelectorAll(".btn1");
function deselectAll(){
// Loop over all the menu items
items.forEach(function(item){
item.classList.remove("active"); // Remove the active class if its there
});
}
/* Mini menu CSS */
/* Style the buttons */
#menu{
margin-top:50px;
display: inline-flex;
margin-left: 15px;
margin-right: 5px;
list-style-type:none;
}
.btn1 {
top:3px;
letter-spacing: 1.8px;
border: none;
outline: none;
padding: 3px 12px;
cursor: pointer;
font-size: 18px;
border-radius: 2rem;
transition: 0.2s;
position: relative;
text-align: center;
align-items: center;
justify-content: center;
overflow: visible;
color: #000;
font-family: Proxima Nova;
font-weight: bold;
/* Give non-active items an invisible 2px border
so that when they do become active the overall
size of the element doesn't shift around. */
border: 1px solid rgba(0,0,0,0);
}
.active {
border-color: #366eaf;
border-width: 2px;
border-style: solid;
}
<ul id="menu">
<li class="btn1 active">ALL</li>
<li class="btn1">MENU1</li>
<li class="btn1">MENU2</li>
<li class="btn1">MENU3</li>
<li class="btn1">MENU4</li>
<li class="btn1">MENU5</li>
</ul>
Related
I have this dropdown menu of multiple different bubbles and I want the menu that drops down underneath the bubbles to close when I click elsewhere, the last line of JS code that I provided in my example was my attempt at making this work but it seems to not be working for some reason. I included the total code for what I'm doing.
function toggleVisibility(link) {
// get the corresponding list
var list = link.parentElement.nextElementSibling;
// toggle the visibility of the list
if (list.style.display === "none") {
// hide all other lists
var otherLists = document.querySelectorAll(".dropdown-list-models");
for (var i = 0; i < otherLists.length; i++) {
otherLists[i].style.display = "none";
}
// position the selected list below the previous list
list.style.top = (link.parentElement.offsetTop + link.parentElement.offsetHeight) + "px";
// show the selected list
list.style.display = "block";
} else {
list.style.display = "none";
}
}
var container = document.querySelector(".dropdown-container-models");
container.addEventListener("click", function() {
var list = this.querySelector("ul");
if (list.style.display === "none") {
list.style.display = "block";
} else {
list.style.display = "none";
}
});
// add event listeners to each list item
var listItems = document.querySelectorAll(".dropdown-container-models ul li");
listItems.forEach(function(listItem) {
listItem.addEventListener("click", function() {
var link = this.querySelector("a");
window.location.href = link.href;
});
});
// Get the dropdown menu
var dropdownMenu = document.getElementById("myDropdownMenu");
// When the user clicks anywhere outside of the dropdown menu, close it
window.onclick = function(event) {
if (!event.target.matches('.dropdown-list-models')) {
dropdownMenu.classList.remove('show');
}
}
a {
color: white;
text-decoration: none;/* Change this to the desired color */
transition: #04AA6D 0.2s;
}
.dropdown-container-models {
position: relative; /* create a positioning context for the list items */
background-color: #333;
color: white;
text-decoration: none;
width: 150px;
text-align: center;
transition: background-color 0.2s;
display: inline-block;
cursor: pointer;
font-family: Arial, Helvetica, sans-serif;
border-radius: 10px;
}
.dropdown-container-models ul li {
cursor: pointer;
}
.dropdown-list-models {
position: absolute; /* position the list items absolutely */
display: none; /* hide the list by default */
top: 100px; /* hide the list by default */
list-style-type: none; /* remove the bullet points for the list items */
padding: 0; /* remove the padding for the list */
left: 0; /* position the list items at the left edge of the list */
transition: border 0.2s; /* add a transition effect for the border */
background-color: #b0b0b0;
color: black;
text-decoration: none;
width: 150px;
text-align: center;
transition: background-color 0.2s;
font-family: Arial, Helvetica, sans-serif;
border-radius: 10px;
}
.dropdown-list-models.show {
display: block; /* Show the menu when the .show class is added */
}
.dropdown-list-models li:hover {
background-color: #04AA6D;
transition: background-color 0.2s;
border-radius: 10px;/* change the background color of the list items to green when they are hovered over */
}
.dropdown-list-models li {
color: black; /* set the color of the list items to black */
text-align: center;
transition: #04AA6D 0.2s;
}
<div class="dropdown-container-models">
<p>Global Models</p>
<ul class="dropdown-list-models" id="myDropdownMenu">
<li>GFS</li>
<li>CMC</li>
<li>ECMWF</li>
</ul>
</div>
<div class="dropdown-container-models">
<p>Mesoscale Models</p>
<ul class="dropdown-list-models" id="myDropdownMenu">
<li>NAM 12km</li>
<li>NAM 3km</li>
<li>HRRR</li>
<li>HREF</li>
<li>NBM</li>
</ul>
</div>
<div class="dropdown-container-models">
<p>Ensembles</p>
<ul class="dropdown-list-models" id="myDropdownMenu">
<li>GEFS</li>
<li>GEPS</li>
<li>EPS</li>
</ul>
</div>
<div class="dropdown-container-models">
<p>Super Ensemble</p>
</div>
I'm sure there are several ways of doing this, but the tricky thing is that elements like <ul> do not have a blur event. Because of this, you have to sort of manually detect when the user clicks outside of an element.
I added 2 functions that basically utilize the elementsFromPoint() method and an event listener on the body. With this, you can get a list of all elements located at the x/y positions of the mouse when the user clicks anywhere in the document. Then you just check to see if your dropdown element is at the clicked location, if not you can trigger some other action (passed in as a function), like hiding the dropdown.
I also took out a bit of your original code because it wasn't really necessary. It seemed like you had multiple method of showing/hiding the dropdowns all in the code together, which made for some weird results. So here is a simplified version with the added blur detection:
document.querySelectorAll(".dropdown-container-models").forEach(d => {
d.addEventListener("click", e => {
const dropdown = e.target.closest(".dropdown-container-models").querySelector("ul")
if(dropdown) {
dropdown.style.display = "block"
_ElementBlur(e.target, () => {
dropdown.style.display = "none"
})
}
})
})
document.querySelectorAll(".dropdown-container-models ul li").forEach(listItem => {
listItem.addEventListener("click", e => {
window.location.href = e.target.querySelector("a").href
})
})
// Functions for getting a 'blur' event on an element
const _ElementBlur = (el, f = false) => {
const ac = new AbortController()
document.body.addEventListener("click", _CheckBlur(el, f, ac), { signal: ac.signal })
}
const _CheckBlur = (el, f = false, ac) => {
return e => {
if(!document.elementsFromPoint(e.clientX, e.clientY).filter(efp => efp == el).length || !document.elementsFromPoint(e.clientX, e.clientY).length) {
if(f && typeof(f) == "function") f()
ac.abort()
}
}
}
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
a {
color: white;
text-decoration: none;/* Change this to the desired color */
transition: #04AA6D 0.2s;
}
.dropdown-container-models {
position: relative; /* create a positioning context for the list items */
background-color: #333;
color: white;
text-decoration: none;
width: 150px;
text-align: center;
transition: background-color 0.2s;
display: inline-block;
cursor: pointer;
font-family: Arial, Helvetica, sans-serif;
border-radius: 10px;
}
.dropdown-container-models ul li {
cursor: pointer;
}
.dropdown-list-models {
position: absolute; /* position the list items absolutely */
display: none; /* hide the list by default */
top: 100px; /* hide the list by default */
list-style-type: none; /* remove the bullet points for the list items */
padding: 0; /* remove the padding for the list */
left: 0; /* position the list items at the left edge of the list */
transition: border 0.2s; /* add a transition effect for the border */
background-color: #b0b0b0;
color: black;
text-decoration: none;
width: 150px;
text-align: center;
transition: background-color 0.2s;
font-family: Arial, Helvetica, sans-serif;
border-radius: 10px;
}
.dropdown-list-models.show {
display: block; /* Show the menu when the .show class is added */
}
.dropdown-list-models li:hover {
background-color: #04AA6D;
transition: background-color 0.2s;
border-radius: 10px;/* change the background color of the list items to green when they are hovered over */
}
.dropdown-list-models li {
color: black; /* set the color of the list items to black */
text-align: center;
transition: #04AA6D 0.2s;
}
<div class="dropdown-container-models">
<p>Global Models</p>
<ul class="dropdown-list-models">
<li>GFS</li>
<li>CMC</li>
<li>ECMWF</li>
</ul>
</div>
<div class="dropdown-container-models">
<p>Mesoscale Models</p>
<ul class="dropdown-list-models">
<li>NAM 12km</li>
<li>NAM 3km</li>
<li>HRRR</li>
<li>HREF</li>
<li>NBM</li>
</ul>
</div>
<div class="dropdown-container-models">
<p>Ensembles</p>
<ul class="dropdown-list-models">
<li>GEFS</li>
<li>GEPS</li>
<li>EPS</li>
</ul>
</div>
<div class="dropdown-container-models">
<p>Super Ensemble</p>
</div>
I have a search bar on my header that I made hidden by default with a button next to it to show/hide it depending on certain conditions. I made the button content using Font Awesome where I put a search icon if the search bar is hidden to indicate "show search", and a right chevron icon if the search bar is shown to indicate "hide search."
The way I wrote my js is so that upon clicking the button, if the event target contains certain classes, the search bar will show/hide and the problem is that the event target can be either the i element (Font Awesome) or the button element. This isn't a problem when clicking to show the search bar, but when clicking to hide it, I can't seem to get the callback function to trigger when the event target is the button element. I really hope I'm making sense.
Here's my JSFiddle -- https://jsfiddle.net/42uoLsrk/2/
function showHideSearch(e) {
e.preventDefault;
const searchBar = document.querySelector("#search");
const searchButton = document.querySelector("#search-button");
if (
e.target.classList.contains("show-btn") ||
e.target.classList.contains("fa-search")
) {
searchBar.classList.add("show-search");
searchButton.innerHTML = `<i class="fas fa-chevron-right"></i>`;
} else if (
e.target.classList.contains("fa-chevron-right") ||
e.target.innerHTML == `<i class="fas fa-chevron-right"></i>`
) {
searchBar.classList.remove("show-search");
searchButton.innerHTML = `<i class="fas fa-search"></i>`;
}
}
Line 24 in JS in particular is where I'm struggling:
e.target.innerHTML == `<i class="fas fa-chevron-right"></i>`
I feel like it really should work, since when the search bar is shown, the innerHTML of the button element is exactly that, but it's not working.
Thanks in advance.
I created an updated version of the jsfiddle here. I fixed a few things, first since you're only getting an element by I'd just use getElementById. Next the button will always have a fairly chance of being pressed regardless of whether you are closing or opening the input field, so you should create a variable that checks whether the input is open or closed. If it's open and the button is clicked close it and vice versa.
const searchDiv = document.getElementById("search-div");
let open = false;
// ADD EVENT LISTENERS
searchDiv.addEventListener("click", showHideSearch);
// FUNCTION: SHOW/HIDE SEARCH BAR ON BUTTON CLICK
function showHideSearch(e) {
e.preventDefault;
const searchBar = document.querySelector("#search");
const searchButton = document.querySelector("#search-button");
if (
(e.target.classList.contains("show-btn") ||
e.target.classList.contains("fa-search")) && !open
) {
searchBar.classList.add("show-search");
searchButton.innerHTML = `<i class="fas fa-chevron-right"></i>`; open = true;
} else if (
( e.target.classList.contains("fa-chevron-right") ||
e.target.id == "search-button") && open
) {
searchBar.classList.remove("show-search");
searchButton.innerHTML = `<i class="fas fa-search"></i>`;
open = false;
}
}
/* GENERAL */
:root {
--light-color: #ccc;
--lighter-color: #f4f4f4;
--dark-color: #333;
--darker-color: #222;
--brand-color: #ff4;
--danger: #f44;
--danger-dark: #c00;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: var(--dark-color);
color: var(--light-color);
font-family: "Trebuchet MS";
}
ul li {
list-style: none;
}
button,
input {
outline: none;
}
/* UTILITY */
.highlight {
color: var(--brand-color);
}
.show-search {
width: 100% !important;
border: black 2px solid;
padding: 0.6rem 1rem;
}
/* HEADER */
header {
background: var(--darker-color);
display: flex;
flex-direction: row;
align-items: center;
text-align: center;
justify-content: space-between;
padding: 1.8rem 6rem;
width: 100%;
}
#logo {
font-size: 2.4rem;
font-weight: 200;
}
#search-div {
width: auto;
height: auto;
display: flex;
gap: 0.4rem;
}
.show-btn {
padding: 0.6rem 0.7rem;
background: var(--light-color);
border-radius: 5px;
border: none;
transition: ease-in 300ms;
font-size: 1.2rem;
cursor: pointer;
height: 100%;
width: 3rem;
}
.show-btn:hover {
background: var(--brand-color);
transition: ease-in 300ms;
}
#search {
width: 0;
height: 100%;
background: var(--lighter-color);
color: var(--darker-color);
font-size: 1.2rem;
border-radius: 2px;
transition: ease-in 300ms;
border: none;
}
<head>
<script src="https://kit.fontawesome.com/3ad7573e76.js" crossorigin="anonymous"></script>
</head>
<body>
<header>
<div id="logo-div">
<h1 id="logo">
<span class="highlight"><i class="fas fa-user-friends"></i></span> My<span
class="highlight">Contact</span>List
</h1>
</div>
<div id="search-div">
<button id="search-button" class="show-btn"><i class="fas fa-search"></i></button>
<input id="search" type="text" placeholder="Search contacts...">
</div>
</header></body>
If you require any more clarification please don't hesitate to ask.
<li className={styles.link + " " + styles.hideOnMobile}>
<div className={styles.dropdownMenu}>
<button className={styles.dropbtn}>Product</button>
<div className={styles.dropdownContent}>
<a
href="#"
onClick={this._trackClick.bind(this, "header")}
>
Link 1
</a>
<a
href="#"
onClick={this._trackClick.bind(this, "header")}
>
Link 2
</a>
</div>
</div>
</li>
.dropdownMenu {
position: relative;
display: inline-block;
}
.dropbtn {
padding: 14px 16px;
font-size: 16px;
border: none;
outline: none;
margin: 0;
&:hover{
background-color: $color-active-dark;
cursor: pointer;
}
}
.dropdownContent {
display: none;
position: absolute;
background-color: $color-active-dark;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
&:hover {
display: block;
cursor: pointer;
}
a {
float: none;
text-align: left;
padding: 12px 16px;
text-decoration: none;
display: block;
&:hover{
background-color: $color-active-dark;
cursor: pointer;
}
}
}
This is my code, currently it doesn't seem to change the display to block when I hover over it and I'm not sure why. It is suppose to be a dropdown menu on top nav bar where when I hover, Link 1 and Link 2 is suppose to dropdown, but right now when I hover, the product button changes color. I'm pretty new at front-end, so any help is appreciated.
Add an extra line (extra selector) to your css to open submenu on hover. In plain css:
.dropdownContent:hover,
.dropbtn:hover + div {
display: block;
cursor: pointer;
}
You asked for the dropdown on the hover trigger. This is not the "toggle" mechanism for touchscreen because that has to be done with Javascript.
update
Your other question: How to toggle (open/close on click) the dropdown?
<script>
var Buttons = document.querySelectorAll(".dropbtn");
for (var i = 0; i < Buttons.length; i++) {
Buttons[i].addEventListener("click", function(event) {
var Divs = document.querySelectorAll(".dropdownContent");
var Shown = (this.nextElementSibling.classList.contains("show"));
for (var j = 0; j < Divs.length; j++) Divs[j].classList.remove("show");
if (Shown) this.nextElementSibling.classList.remove("show");
else this.nextElementSibling.classList.add("show");
});
}
</script>
with the following extra css at the end of your current nav css
.dropdownContent {
display: none;
}
.dropdownContent.show {
display: block;
}
Ofcourse this Javascript will open only one dropdown at a time if you have a navigation with multiple <li class="link hideOnMobile"> items.
TLDR; The functionality I'm trying to create in this code example is upon clicking a box (collapsible has active class), and then you click on the search box, the active class is removed closing the collapsible. Currently, the remove class is not working. Any idea why?
In more detail:
I have a list of collapsible blocks get an active class when they are clicked. You can search a search box to filter out which block you want to be displayed, and thus click on it to display more content. I have realized that when you go back to search and didn't 'unclick' a box (to close the collapsible) the box is still active (which makes perfect sense).
I had an idea that upon search box focus, I would loop through all the collapsible and remove the active class itself (in turn, closing the collapsible).
I've gotten to the point where I can find which collapsible is active, but I cannot remove the active class.
Is this because the box was initially clicked to add the class and has to be physically clicked once again to remove it?
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
function searchClick() {
var searchTable;
searchTable = document.getElementById("search-table");
faqButtons = searchTable.getElementsByTagName("button");
for (i = 0; i < faqButtons.length; i++) {
if (faqButtons[i].classList.contains("active")) {
console.log('THIS ONE: ', faqButtons[i]);
faqButtons[i].classList.remove("active");
}
}
}
.collapsible {
display: flex;
justify-content: space-between;
background-color: white;
color: black;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 20px;
}
.collapsible span {
padding-left: 5px;
padding-right: 5px;
}
.collapsible .active,
.collapsible:hover {
background-color: #333;
color: white;
}
.content {
padding: 0 18px;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
.content p {
margin-top: 10px;
}
<div class="search-faq">
<input autocomplete="off" type="text" id="search-faq" placeholder="Search for FAQ" onfocus="searchClick()" />
</div>
<div id="search-table" class="superHidden">
<div id="wolfandgrizzly-FAQ-search">
<h1>A to B sales</h1>
<button class="collapsible"><span>What are our shipping policies?</span></button>
<div class="content">
<p>
They are crazy cool.
</p>
</div>
<button class="collapsible"><span>Are you making more products?</span></button>
<div class="content">
<p>
We'll sell you more very soon
</p>
</div>
</div>
I don't see where you are getting that the active class is not being removed. It doesn't appear that there is a problem with that. I think the problem is that you are showing the answers via maxHeight setting, but you aren't resetting it when you click the search box. I've updated it in this snippet, but essentially it boiled down to adding the following in your loop:
var content = faqButtons[i].nextElementSibling
content.style.maxHeight = null
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
function searchClick() {
var searchTable;
searchTable = document.getElementById("search-table");
faqButtons = searchTable.getElementsByTagName("button");
for (i = 0; i < faqButtons.length; i++) {
if (faqButtons[i].classList.contains("active")) {
console.log('THIS ONE: ', faqButtons[i]);
faqButtons[i].classList.remove("active");
}
var content = faqButtons[i].nextElementSibling
content.style.maxHeight = null
}
}
.collapsible {
display: flex;
justify-content: space-between;
background-color: white;
color: black;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 20px;
}
.collapsible span {
padding-left: 5px;
padding-right: 5px;
}
.collapsible .active,
.collapsible:hover {
background-color: #333;
color: white;
}
.content {
padding: 0 18px;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
.content p {
margin-top: 10px;
}
<div class="search-faq">
<input autocomplete="off" type="text" id="search-faq" placeholder="Search for FAQ" onfocus="searchClick()" />
</div>
<div id="search-table" class="superHidden">
<div id="wolfandgrizzly-FAQ-search">
<h1>A to B sales</h1>
<button class="collapsible"><span>What are our shipping policies?</span></button>
<div class="content">
<p>
They are crazy cool.
</p>
</div>
<button class="collapsible"><span>Are you making more products?</span></button>
<div class="content">
<p>
We'll sell you more very soon
</p>
</div>
</div>
Here's an approach that uses as little JavaScript as possible. If JavaScript is disabled, the only thing that will break is the search box. Sections will still open and close as expected when clicked.
The accordion stores its state in checkboxes, one in each section. Each section's title is a label element which toggles that section's checkbox when clicked. The sections are expanded and collapsed using CSS :checked selectors.
var sections = [].slice.call(document.querySelectorAll(".accordion li")),
searchAccordion = function() {
var value = document.getElementById("search").value.toLowerCase();
sections.map(function(section) {
var content = section.textContent.toLowerCase();
section.querySelector("input").checked = content.includes(value);
});
};
body {
font-family: sans-serif;
}
.accordion {
padding-left: 0;
margin: -1rem;
}
.accordion li {
list-style-type: none;
}
.accordion input {
display: none;
}
.accordion label {
background-color: #eee;
transition: background-color 100ms;
cursor: pointer;
font-size: 1.2rem;
padding: 1rem;
display: block;
}
.accordion label:hover {
background-color: #444;
color: white;
}
.accordion .content {
padding: 1rem;
display: none;
}
.accordion input:checked ~ .content {
display: block;
}
<input id="search" onKeyup="searchAccordion()" type="text" placeholder="Search for FAQ" autocomplete="off">
<h1>A to B sales</h1>
<ul class="accordion">
<li>
<input type="checkbox" id="section1">
<label for="section1">What are our shipping policies?</label>
<div class="content">They are crazy cool.</div>
</li>
<li>
<input type="checkbox" id="section2">
<label for="section2">Are you making more products?</label>
<div class="content">We'll sell you more very soon</div>
</li>
</ul>
I am trying to create a disappearing drop down menu that disappears into the top of the page, and you can only see the word 'open'. This opens the the menu, the word open changes to the word close which when clicked makes the menu disappear again. Help would be much appricated.
<html>
<head>
<title>dropdown</title>
<link rel="stylesheet" type="text/css" href="dropdown_css.css">
<script type = "text/javascript">
function navagate(menu) {
var panel = document.getElementById(menu),maxh = "-362px", navg = document.getElementById('navag');
if (panel.style.marginTop == maxh){
panel.style.marginTop = "0px";
navag.innerHTML = "Close";
}
else {
panel.style.marginTop = maxh;
navag.innerHTML = "Open";
}
}
window.onload = function(){panel.style.marginTop = "-362px";}
</script>
<body>
<div id = "panel">
<ul>
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
</ul>
<div id ="sections_button">
<a onclick = "navigate ('panel')" id = "navag">Open</a>
</div>
</div>
</body>
</body>
</html>
#panel {
width : 160px;
height: 130px;
background-color: gray;
margin-left: 30px;
margin-top:20px;
}
#panel li {
list-style-type: none;
}
Here, I've made a JS fiddle that may help you out: http://jsfiddle.net/942z0nhh/ I did not play around with the styling at all.
A few things I noticed:
You're making some mistakes that I think you wouldn't make if you indented properly. Take a look here, where you closed your body twice:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
</div>
</div>
</body>
</body>
Second, you have some spelling mistakes:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
vs
function navagate(menu) {
You can see there that your function would never be called because of it.
Lastly, your 'open' and 'close' a here:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
Was within the div your function was overwriting. The function would change it to 'close'- but then it wouldn't be visible to the user anyway! I moved it above, which I hope makes sense.
Please let me know if you have any other questions, or if I misunderstood.
You could also do it only with CSS. It's the "css checkbox hack". I'm having it not like you want it but it is pretty close. Changing the text from open to close should be also possible.
At the moment, I don't know how to move the open/close label below the ul list.
*, html {
padding: 0px;
font-family: sans-serif;
}
/* Checkbox Hack */
input[type=checkbox] {
position: absolute;
display: none;
}
label {
display: block;
cursor: pointer;
content: "close";
}
/* Default State */
#wrapper {
display: block;
background: gray;
color: white;
text-align: center;
}
/* Toggled State */
input[type=checkbox]:checked ~ #menu {
display: block;
background: lightgray;
color: black;
top:0px;
}
.menuToggle ul{
display: none;
width: 100%;
}
#menu {
padding-top: 5px;
margin: 0px;
list-style: none;
}
<div id="wrapper">
<div class="menuToggle">
<label for="toggle-1">open</label>
<input type="checkbox" id="toggle-1"/>
<ul id="menu">
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
</ul>
</div>
</div>
With jQuery you could do it like the example below.
I think it is now almost like you wanted it. Maybe some styling improvements are required.
With the css hack I couldn't manage the text change. With js you have more possibilities. You could also improve/modify the animations.
$(function() {
var $menuButton = $('#openButton');
var $menu = $('#menu');
var btnToggleAnim = function() {
$menuButton.animate({opacity: 'toggle'}, "fast");
};
var menuToggleAnim = function() {
$('#menu').animate({
height:'toggle',
//opacity: 'toggle'
}, { duration: "slow" });
};
$('#closeButton,#openButton').on('click', function() {
menuToggleAnim();
btnToggleAnim();
});
});
*, html {
padding: 0px;
font-family: sans-serif;
}
a {
text-decoration:none;
}
#openButton {
display:block;
background: gray;
color: #fff;
text-decoration: none;
border: 2px solid lightgray;
border-radius: 15px;
}
#closeButton{
display: block;
background: gray;
color: #fff;
text-align: center;
border: 2px solid lightgray;
border-bottom-left-radius: 13px;
border-bottom-right-radius: 13px;
}
#wrapper {
display: block;
text-align: center;
}
#menu {
display: none;
background: lightgray;
color: black;
padding-top: 5px;
margin: 0px;
list-style: none;
}
#menu {
color: #000;
text-decoration: none;
border: 2px solid lightgray;
border-radius: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
open
<ul id="menu">
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
<li>close</li>
</ul>
</div>