I am trying to do a side navigation that:
Just have ONE open sublist (close other)
Select only the clicked link in sublist
There are tons of examples out there, but I have not found any good sample in Vanilla Javascript.
HTML
<div class="sidenav">
Home
<button class="btn">Module 1</button>
<div class="list">
Link 1
Link 2
Link 3
</div>
<button class="btn">Module 2</button>
<div class="list">
Link 1
Link 2
Link 3
</div>
</div>
Javascript
var dropdown = document.getElementsByClassName("btn");
var i;
for (i = 0; i < dropdown.length; i++) {
dropdown[i].addEventListener("click", function() {
var dropdownContent = this.nextElementSibling;
if (dropdownContent.style.display === "block") {
dropdownContent.style.display = "none";
} else {
dropdownContent.style.display = "block";
}
});
}
The complete CSS is found on this Fiddle:
http://jsfiddle.net/q2en6djg/1/
Any clue, hint or help is appreciated.
You can consider an active CSS class to make it easier:
var dropdown = document.getElementsByClassName("btn");
var l = dropdown.length;
var i;
for (i = 0; i < l; i++) {
dropdown[i].addEventListener("click", function() {
for (var j = 0; j < l; j++) {
if (this != dropdown[j])
dropdown[j].classList.remove('active')
}
this.classList.toggle('active');
});
}
/*To select the sub item*/
var sub = document.querySelectorAll(".list a");
for (var i = 0; i < sub.length; i++) {
sub[i].addEventListener("click", function() {
this.classList.toggle('active');
});
}
* {
font-family: "Trebuchet MS", sans-serif;
font-size: 7em;
}
.sidenav {
margin-top: 0px;
height: auto;
width: 200px;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #555;
overflow-x: hidden;
}
.sidenav a,
.btn {
padding: 10px 10px 10px 20px;
text-decoration: none;
font-size: 17px;
color: #fff;
display: block;
text-align: left;
border: none;
background: none;
width: 100%;
cursor: pointer;
outline: none;
border-bottom: 1px solid #777;
box-sizing:border-box;
}
.sidenav a:hover,
.sidenav a.active,
.btn:hover,
.btn.active {
background-color: #777;
}
.list {
display: none;
background-color: #999;
padding-left: 0px;
}
.active+.list {
display: block;
}
<div class="sidenav">
Home
<button class="btn">Module 1</button>
<div class="list">
Link 1
Link 2
Link 3
</div>
<button class="btn">Module 2</button>
<div class="list">
Link 1
Link 2
Link 3
</div>
</div>
Related
Here I am showing tabs with basic data. It will go to next tab whenever I click next tab button.
Can anybody help me how to switch tabs automatically after few seconds, like first 30 sec tab1,next 30 sec tab2 - after tab2 it should come to tab1
function openPage(pageName, elmnt, color) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].style.backgroundColor = "";
}
document.getElementById(pageName).style.display = "block";
elmnt.style.backgroundColor = color;
}
// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();
var updatedTime = document.lastModified;
document.getElementById("time1").innerHTML = updatedTime;
document.getElementById("time2").innerHTML = updatedTime;
* {
box-sizing: border-box
}
/* Set height of body and the document to 100% */
body,
html {
height: 100%;
margin: 0;
font-family: Arial;
}
/* Style tab links */
.tablink {
background-color: #555;
color: white;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
font-size: 17px;
width: 25%;
}
.tablink:hover {
background-color: #777;
}
/* Style the tab content (and add height:100% for full page content) */
.tabcontent {
color: white;
display: none;
padding: 100px 20px;
height: 100%;
}
#Home {
background-color: red;
}
#News {
background-color: green;
}
<button class="tablink" onclick="openPage('Home', this, 'red')">Home</button>
<button class="tablink" onclick="openPage('News', this, 'green')" id="defaultOpen">News</button>
<div id="Home" class="tabcontent">
<h3>Home</h3>
<p>Home is where the heart is..</p>
<div class="footer">
<p>Last Updated On : <span id="time1"></span><br>
<p>Software Version</p>
</div>
</div>
<div id="News" class="tabcontent">
<h3>News</h3>
<p>Some news this fine day!</p>
<div class="footer">
<p>Last Updated On : <span id="time2"></span><br>
<p>Software Version</p>
</div>
</div>
You mean this?
I would perhaps clear the timeout if someone clicks any tab in case they want to stay on it
function openPage(pageName, elmnt, color) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].style.backgroundColor = "";
}
document.getElementById(pageName).style.display = "block";
elmnt.style.backgroundColor = color;
}
window.addEventListener("load", function() {
// Get the element with id="defaultOpen" and click on it
const tabs = document.querySelectorAll(".tablink");
let cnt = 0;
for (let i = 0; i < tabs.length; i++) {
if (tabs[i].id === "defaultOpen") {
cnt = i;
break;
}
}
tabs[cnt].click(); // clicks defaultOpen first time
const tId = setInterval(function() {
cnt++;
if (cnt >= tabs.length) cnt = 0;
tabs[cnt].click();
}, 3000);
const lmID = setInterval(function() {
var updatedTime = document.lastModified;
document.getElementById("time1").innerHTML = updatedTime;
document.getElementById("time2").innerHTML = updatedTime;
},1000)
})
* {
box-sizing: border-box
}
/* Set height of body and the document to 100% */
body,
html {
height: 100%;
margin: 0;
font-family: Arial;
}
/* Style tab links */
.tablink {
background-color: #555;
color: white;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
font-size: 17px;
width: 25%;
}
.tablink:hover {
background-color: #777;
}
/* Style the tab content (and add height:100% for full page content) */
.tabcontent {
color: white;
display: none;
padding: 100px 20px;
height: 100%;
}
#Home {
background-color: red;
}
#News {
background-color: green;
}
<button class="tablink" onclick="openPage('Home', this, 'red')">Home</button>
<button class="tablink" onclick="openPage('News', this, 'green')" id="defaultOpen">News</button>
<div id="Home" class="tabcontent">
<h3>Home</h3>
<p>Home is where the heart is..</p>
<div class="footer">
<p>Last Updated On : <span id="time1"></span><br>
<p>Software Version</p>
</div>
</div>
<div id="News" class="tabcontent">
<h3>News</h3>
<p>Some news this fine day!</p>
<div class="footer">
<p>Last Updated On : <span id="time2"></span><br>
<p>Software Version</p>
</div>
</div>
https://ataqfuel.com/pages/home-page-v2
I am trying to get button 2 and 3 to close like button 1 does when clicking outside of the dropdown menu. I tried adding myFunction1 code to myFunction2 and myFunction3 code but I'm not sure if I messed up the naming or what because all the dropdowns stopped functioning then.
function myFunction1() {
document.getElementById("myDropdown1").classList.toggle("show");
document.getElementById("myDropdown1").addEventListener('click', function(event) {
event.stopPropagation();
});
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn1')) {
var dropdowns = document.getElementsByClassName("dropdown-content1");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
document.getElementById("dropbtn1").addEventListener('click', function(event) {
event.stopPropagation();
});
function myFunction2() {
document.getElementById("myDropdown2").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn2')) {
var dropdowns = document.getElementsByClassName("dropdown-content2");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
function myFunction3() {
document.getElementById("myDropdown3").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn3')) {
var dropdowns = document.getElementsByClassName("dropdown-content3");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
CSS : .dropbtn {
margin: 5%;
background-color: #d3d3d3;
color: gray;
padding: 16px;
font-size: 16px;
font-weight: 500;
border: none;
cursor: pointer;
}
.dropbtn:hover,
.dropbtn:focus {
background-color: #edeb3f;
}
.dropdown {
position: relative;
display: inline;
min-width: 160px;
}
.dropdown-content {
display: none;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {
background-color: #ddd;
}
.show {
display: block;
}
$('.moderate .button').on('click', (event) => {
$(event.target).siblings('.dropdown')
.toggleClass('is-open');
});
$(document).click(function(e) {
$('.moderate')
.not($('.moderate').has($(e.target)))
.children('.dropdown')
.removeClass('is-open');
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.4.0/css/bulma.css" rel="stylesheet" />
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<style>
.dropdown {
box-shadow: 0 0 2px #777;
display: none;
left: 0;
position: absolute;
padding: 2px;
z-index: 10;
}
.dropdown a {
font-size: 12px;
padding: 4px;
}
.dropdown.is-open {
display: block;
}
</style>
<div class="control moderate">
<button class="button is-small" type="button">
moderate
</button>
<div class="box dropdown">
<ul>
<li><a class="nav-item">edit</a></li>
<li><a class="nav-item">delete</a></li>
<li><a class="nav-item">block user</a> </li>
</ul>
</div>
</div>
<div class="control moderate">
<button class="button is-small" type="button">
moderate
</button>
<div class="box dropdown">
<ul>
<li><a class="nav-item">edit</a></li>
<li><a class="nav-item">delete</a></li>
<li><a class="nav-item">block user</a></li>
</ul>
</div>
</div>
You can use full screen width and height fixed backdrop for that. And after backdrop click close menu. It should be something like this:
jQuery(".backdrop").click(function(){
jQuery("#menu").toggleClass("open");
});
I have a website with three sections containing tabbed areas. I had an older version of this which worked fine, and showed all sections correctly at all times, however as I was changing to a new layout the tabbed sections stopped functioning, I then changed them to some new code and ended up preferring this instead. I then noticed that my content would only show in one section at a time, so some sections do not show up when the page is loaded, unless the tab link is active/clicked.
I recall finding a way to fix this before but I've looked online and can't find anything, and didn't save a version of my old JS code to refer back to. I was hoping someone could help me remember why this happens and how to fix it.
I should note that I have unique IDs for my code and I have not reflected this in my code, as I had that issue the first time round. The unique IDs do not help fix the issue unfortunately.
function openPage(pageName, elmnt, color) {
// Hide all elements with class="tabcontent" by default */
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Remove the background color of all tablinks/buttons
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].style.backgroundColor = "";
}
// Show the specific tab content
document.getElementById(pageName).style.display = "block";
// Add the specific color to the button used to open the tab content
elmnt.style.backgroundColor = color;
}
// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();
h3 {
font-size: 15px;
word-spacing: 2px;
font-weight: 100;
letter-spacing: 1px;
text-transform: uppercase;
font-family: 'IBM Plex Mono', sans-serif;
}
h2 {
font-size: 40px;
color: white;
word-spacing: 2px;
margin-bottom: 15px;
font-weight: 700;
letter-spacing: 1px;
font-family: 'IBM Plex Serif', sans-serif;
}
p {
font-weight: 300;
font-size: 15px;
color: white;
text-align: justify;
line-height: 1.5;
}
.new-section__black {
padding: 5%;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
position: relative;
transition: .5s ease;
background-color: #000;
height: 100%;
}
/* Style tab links */
.tablink {
float: left;
outline: none;
cursor: pointer;
margin: 0 1%;
padding: 5px 5px;
font-size: 17px;
width: 10%;
}
.link-black {
background-color: #fff;
color: #000;
border: 1px solid #000;
}
.link-white {
background-color: #000;
color: #fff;
}
.tablink:first-of-type {
margin-left: 5%;
}
.tablink:last-of-type {
margin-right: 5%;
}
.link-black:active,
.link-black:hover {
background-color: #000;
color: #fff;
box-shadow: 2px 2px 10px #555;
}
.link-white:active,
.link-white:hover {
background-color: #fff;
color: #000;
}
/* Style the tab content (and add height:100% for full page content) */
.tabcontent {
width: 100%;
display: none;
margin-top: 1%;
padding: 100px 20px;
height: 100%;
}
.content-black {
color: #000;
}
.content-white {
color: #fff;
}
.tabcontent .col:first-of-type {
margin-left: 0;
}
#defaultOpen {
display: block;
}
<section class="card new-section__black new_section">
<button class="tablink link-white" onclick="openPage('Tab1', this)" id="defaultOpen">
<h3>Tab1</h3>
</button>
<button class="tablink link-white" onclick="openPage('Tab2', this)">
<h3>Tab2</h3>
</button>
<button class="tablink link-white" onclick="openPage('Tab3', this)">
<h3>Tab3</h3>
</button>
<button class="tablink link-white" onclick="openPage('Tab4', this)">
<h3>Tab4</h3>
</button>
<div id="Tab1" class="tabcontent content-white">
<div class="col span-2-of-2">
<h2>Tab1</h2>
<p>Text</p>
</div>
</div>
<div id="Tab2" class="tabcontent content-white">
<div class="col span-2-of-2">
<h2>Tab2</h2>
<p>Text</p>
</div>
</div>
<div id="Tab3" class="tabcontent content-white">
<div class="col span-2-of-2">
<h2>Tab3</h2>
<p>Text</p>
</div>
</div>
<div id="Tab4" class="tabcontent content-white">
<div class="col span-2-of-2">
<h2>Tab4</h2>
<p>Text</p>
</div>
</div>
</section>
Here is a CodePen example of what I have.
If you have multiple sets of "tabs" on the page, you need to scope your interactions to that specific <section>.
function openPage(pageName, elmnt, color) {
// Get the parent node, make all DOM selections based on this
var section = elmnt.parentElement;
// Hide all elements with class="tabcontent" by default */
var i, tabcontent, tablinks;
tabcontent = section.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Remove the background color of all tablinks/buttons
tablinks = section.getElementsByClassName("tablink");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].style.backgroundColor = "";
}
// Show the specific tab content
section.getElementById(pageName).style.display = "block";
// Add the specific color to the button used to open the tab content
elmnt.style.backgroundColor = color;
}
// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();
Also, you repeat element id values everywhere, this is not proper HTML and will lead to unexpected behavior. Each id should be unique. (you currently have multiple "defaultOpen" elements, you have multiple "Tab1", "Tab2", etc... rename them with no repeated values)
I found some really helpful tutorial to help me use javascript to expand and collapse content, but now I can't figure out how to make it only expand one at a time... So that when one div is expanded, if you click to expand another one, it collapses the first one. Any ideas? Here is the tutorial that i have followed
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";
}
});
}
.collapsible {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.content {
padding: 0 18px;
display: none;
overflow: hidden;
background-color: #f1f1f1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="collapsible"> Expand </button>
<div class="content">
<p>Some content</p>
</div>
You can select all the <div class="content"> and then set each of those to display: none. Snippet below:
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
//add new code here
var contents = document.querySelectorAll('div.content')
contents.forEach((content) => {
content.style.display = "none"
})
var content = this.nextElementSibling;
if (content.style.display === "block") {
content.style.display = "none";
} else {
content.style.display = "block";
}
});
}
.collapsible {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.content {
padding: 0 18px;
display: none;
overflow: hidden;
background-color: #f1f1f1;
}
<button class="collapsible"> Expand </button>
<div class="content">
<p>Some content</p>
</div>
<button class="collapsible"> Expand </button>
<div class="content">
<p>Some content2</p>
</div>
Hope this helps
i am trying to create a menu with JS, when i click on the first menu item and it is open, then i want when i click on the next item i want the first one to close and the second one to open and when i am clicking on the open menu item i want it to close. also when i click anywhere if i can make it close as well...
here the code i have
HTML
<div class="container-header">
<div class="navbar">
<ul>
<li>
<a onclick="dropdownToggle(event)"><span>Products</span></a>
<div class="dropdown">
<ul class="submenu-img">
<li><a><img src="2015_images/img.png">title</a></li>
<li><a><img src="2015_images/img.png">title</a></li>
<li><a><img src="2015_images/img.png">title</a></li>
<li><a><img src="2015_images/img.png">title</a></li>
<li><a><img src="2015_images/img.png">title</a></li>
</ul>
</div>
</li>
<li><a onclick="dropdownToggle(event)"><span>Services</span></a>
<div class="dropdown">
<ul class="submenu">
<li><a>item</a></li>
<li><a>item</a></li>
<li><a>item</a></li>
<li><a>item</a></li>
</ul>
</div>
</li>
<li><a onclick="dropdownToggle(event)"> <span>Softwares</span></a>
<div class="dropdown">
<ul class="submenu">
<li><a>item</a></li>
<li><a>item</a></li>
<li><a>item</a></li>
<li><a>item</a></li>
</ul>
</div>
</li>
</ul>
</div>
CSS
* {
box-sizing: border-box;
}
ul {
list-style: none;
}
.navbar {
width: 100%;
text-align: center;
position: absolute;
top: -500px;
background-color: #585859;
transition: top 0.3s;
z-index: 1;
}
#media screen and (min-width: 768px) {
.navbar {
line-height: 65px;
width: auto;
position: static;
}
}
.navbar ul {
margin: 0;
padding: 0;
}
.navbar li {
vertical-align: middle;
color: #fff;
padding: 10px;
border-bottom: 5px solid #fff;
}
#media screen and (min-width: 768px) {
.navbar li {
display: inline-block;
margin-right: 10px;
border: none;
padding: 0;
}
}
.dropdown {
display: none;
}
.dropdown-open {
display: block;
position: absolute;
top: 70px;
left: 0;
background: rgba(88, 88, 89, 0.7);
width: 100%;
}
.submenu {
width: 100%;
display: flex;
align-items: center;
flex-flow: row;
justify-content: center;
padding: 10px 0 !important;
}
.submenu li {
margin: 0 2px;
flex: 0 0 12%;
line-height: normal;
}
and JS
function dropdownToggle(event) {
var dropdownItem = event.target.parentElement.parentElement.getElementsByClassName("dropdown")[0];
if (dropdownItem.classList.contains("dropdown-open")) {
var dropdowns = document.querySelectorAll(".dropdown");
var arrayLength = dropdowns.length;
for (var i = 0; i < arrayLength; i++) {
dropdowns[i].classList.remove("dropdown-open");
}
}
else {
dropdownItem.classList.toggle("dropdown-open");
}
}
I tried on JSFiddle but it is not working so here is a codepen as well..
http://codepen.io/nnns/pen/rLvdgE
The best way will be to put
var dropdowns = document.querySelectorAll(".dropdown");
var arrayLength = dropdowns.length;
for (var i = 0; i < arrayLength; i++) {
dropdowns[i].classList.remove("dropdown-open");
}
in a function and call it at the beginning of your function dropdownToggle(event) so like that every time you call your function you close everything and can open what you want.
EDIT
Do this:
function dropdownToggle(event) {
var dropdownItem =event.target.parentElement.parentElement.getElementsByClassName("dropdown")[0];
var dropdowns = document.querySelectorAll(".dropdown");
var arrayLength = dropdowns.length;
for (var i = 0; i < arrayLength; i++) {
dropdowns[i].classList.remove("dropdown-open");
}
dropdownItem.classList.add("dropdown-open");
}
function dropdownToggle(event) {
var dropdownItem = event.target.parentElement.getElementsByClassName("dropdown")[0];
dropdownItem.classList.remove("dropdown");
var dropdowns = document.querySelectorAll(".dropdown");
var arrayLength = dropdowns.length;
for (var i = 0; i < arrayLength; i++) {
dropdowns[i].classList.remove("dropdown-open");
}
dropdownItem.classList.toggle("dropdown-open");
dropdownItem.classList.add("dropdown");
}
This removes all dropdown open classes and toggles the dropdown that is found in the parent(li) of the a.
To close on body click:
document.all.body.onclick=dropdownToggle(document.all.body);