Need help toggling dropdown menus using the same class (Javascript) - javascript

I'm trying to get this to work for all elements using the class-name '.sub-menu-parent', but I can only get it to work for the first instance of it.
I have tried using a for loop with the index of parentClass, but it doesn't seem to work. Same goes with the '.sub-menu-child' class.
HTML
<nav>
<div class="row">
<img src="resources/img/logos/HTH_Logo_1_2.png" alt="A logo that says 'hearts that heal'" class="logo">
<ul class="main-nav">
<li>Home</li>
<li>About Us <i class="ion-android-arrow-dropdown"></i>
<ul class="drop-down-main sub-menu--child">
<li>Who We Are</li>
<li>Mission Statement</li>
<li>Vision Statement</li>
<li>Our Values</li>
<li>Goals</li>
<li>Objectives</li>
</ul>
</li>
<li>Photo Gallery <i class="ion-android-arrow-dropdown"></i>
<ul class="drop-down-main sub-menu--child">
<li>Group Photos</li>
<li>Retreat Photos</li>
<li>Members Photos</li>
<li>Honorary Members Photos</li>
<li>Our Beloved Children</li>
<li>Activities and Sponsorship Photos</li>
</ul>
</li>
<li>Contact</li>
</ul>
</div>
</nav>
CSS
/* ----- MAIN NAV ----- */
.main-nav {
float: right;
list-style-type: none;
margin-top: 32.5px;
}
.main-nav li {
display: inline;
text-align: center;
}
.main-nav li a:link,
.main-nav li a:visited {
text-decoration: none;
color: #fff;
padding: 5px 10px;
font-weight: 400;
font-size: 80%;
background-color: #c95a6c; /* #484066 */
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.main-nav li a:hover,
.main-nav li a:active {
background-color: #fff;
color: #c95a6c;
}
/* ----- For colors ----- */
.main-nav-color:focus {
color: #c95a6c !important;
background-color: #fff !important; /* #484066 */
}
/* ----- NESTED NAV ----- */
.drop-down-main {
position: absolute;
z-index: 9990;
background-color: #fff;
display: none;
margin-top: 5px;
border: 1px solid #484066;
border-top: none;
}
.show {
display: block;
}
.drop-down-main li {
display: block;
text-align: left;
border-bottom: 1px solid #484066;
width: 100%;
}
.drop-down-main li a:link,
.drop-down-main li a:visited {
display: block;
text-decoration: none;
color: #c95a6c;
font-weight: 400;
font-size: 80%;
background: none; /* #484066 */
border-radius: 0;
padding: 5px 24px 5px 5px;
}
.drop-down-main li:hover,
.drop-down-main li:active {
background-color: #c95a6c;
}
.drop-down-main li a:hover,
.drop-down-main li a:active {
color: #fff;
}
.drop-down-main li:first-child {
margin-top: 10px;
border-top: 1px solid #484066;
}
.drop-down-main li:last-child {
border: none;
}
Javascript
var menuToggle = (function() {
var DOMstrings = {
displayToggle: 'show',
dropParent: '.sub-menu--parent',
dropChild: '.sub-menu--child',
colorToggle: 'main-nav-color',
};
var parentClass = document.querySelector(DOMstrings.dropParent);
var childClass = document.querySelector(DOMstrings.dropChild);
parentClass.addEventListener('click', toggleDropdown, false);
function toggleDropdown() {
childClass.classList.toggle(DOMstrings.displayToggle);
parentClass.classList.toggle(DOMstrings.colorToggle);
};
window.addEventListener('click', function(event) {
if(event.target !== parentClass && event.target.parentNode !== parentClass) {
childClass.classList.remove(DOMstrings.displayToggle);
parentClass.classList.remove(DOMstrings.colorToggle);
}
});
})();
I have also tried using querySelectorAll but it seems you can't use classList Methods with it.

You should use querySelectorAll
Based from this answer: Add event listener to DOM elements based on class
document.querySelector('.class-name'); Will only select the first element having class='class-name'.
For adding event listener to all such elements, use querySelectorAll()
And then update the code where you attach the listener.
var parentClasses = document.querySelectorAll(DOMstrings.dropParent);
for (var i = 0; i < parentClasses.length; i++) {
parentClasses[i].addEventListener('click', setupEventListener(parentClasses[i]), false);
}
function setupEventListener(element){
return function(){
toggleDropdown(element);
}
}
function toggleDropdown(element) {
// since `ul` is a sibling of `a`
element.nextElementSibling.classList.toggle(DOMstrings.displayToggle);
element.classList.toggle(DOMstrings.colorToggle);
};
I believe this should work for your current implementation, however this doesn't include code for toggling the display off.

Related

Links to change colour with css not working properly

I have some code for which I am trying to make a navbar. I have links in the code and I changed them when the page is scrolled up a little. I change the colours ok but cant change on hover to stay permanent? I seem to have tried everything but its like its resetting my css all the time. It works fine with the links but cant seem to change on hover colour to stay the same.
$(document).ready(function() {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll > 10) {
$(".white").css("background", "#362c6e");
$(".white").css("color", "#ffffff");
$(".nav-login").css("color", "#ffffff");
$(".nav-big a:link").css("color", "#ffffff");
$(".nav-more a:link").css("color", "#ffffff");
}
if (scroll < 10) {
$(".white").css("background-color", "rgba(255, 255, 255, 0)");
$(".white").css("color", "#111111");
$(".nav-login").css("color", "#362c6e");
$(".nav-big a:link").css("color", "#362c6e");
$(".nav-more a:link").css("color", "#362c6e");
}
})
})
.image-container-left {
margin-left: 40px;
margin-top: 0px;
}
#nav {
overflow: hidden;
width: 100%;
/* Full width */
border: 0;
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
float: left;
list-style: none;
}
.nav-image-left {
border: 0;
list-style-type: none;
margin: 0;
padding: 0;
margin-right: 5px;
margin-top: 17px;
margin-left: 5px;
float: left;
list-style: none;
}
.nav-big {
border: 0;
list-style-type: none;
margin: 0;
padding: 0;
margin-right: 5px;
margin-top: 37px;
float: left;
list-style: none;
margin-left: 5%;
}
.nav-more {
border: 0;
list-style-type: none;
margin: 0;
padding: 0;
margin-top: 37px;
margin-left: 30px;
;
float: left;
list-style: none;
}
.nav-login {
list-style-type: none;
float: right;
margin-top: 37px;
margin-right: 40px;
color: 362c6e;
}
.nav-big a:hover,
a:visited,
a:link,
a:active {
text-decoration: none;
}
.nav-more a:hover,
a:visited,
a:link,
a:active {
text-decoration: none;
}
.nav-big a:link {
color: #362c6e;
}
.nav-more a:link {
color: #362c6e;
}
.nav-more a:hover {
color: #e73972;
)
.nav-big a:hover {
color: #e73972;
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="nav" class='container-fluid white hidden-xs hidden-sm'>
<ul>
<li class='nav-image-left'>
<div class='image-container-left'>
<a href=index><img src='images/ctbig.png' height='62' alt='image-left' /></a>
</div>
</li>
<li id="nav-big" class='nav-big'><a href='updating'> About us </a></li>
<li class='nav-more'><a href='updating'> Register new job </a></li>
<li class='nav-more'><a href='updating'> Register business </a></li>
<li class='nav-more'><a href='updating'> Contact us </a></li>
<li class='nav-more'><img src='images/users.png' alt='image-right' width='22' /><a href='updating'> Login </a></li>
<li class='nav-login'>0800 038 6210</li>
</ul>
</div>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
Is this what you need?
$(document).ready(function(){
$(window).scroll(function(){
var scroll = $(window).scrollTop();
$('#nav').toggleClass('before10',!(scroll > 10)); // toggle Class ad or remove a class considering the second parameter being true or false
$('#nav').toggleClass('after10',(scroll > 10));// toggle Class ad or remove a class considering the second parameter being true or false
})
})
body{
min-height:700px;
}
.image-container-left {
margin-left:40px;
margin-top:0px;
}
#nav {
overflow: hidden;
width: 100%; /* Full width */
border:0;
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
float: left;
list-style: none;
}
.nav-image-left {
border:0;
list-style-type: none;
margin: 0;
padding: 0;
margin-right: 5px;
margin-top: 17px;
margin-left: 5px;
float: left;
list-style: none;
}
.nav-big {
border:0;
list-style-type: none;
margin: 0;
padding: 0;
margin-right: 5px;
margin-top: 37px;
float: left;
list-style: none;
margin-left:5%;
}
.nav-more {
border:0;
list-style-type: none;
margin: 0;
padding: 0;
margin-top: 37px;
margin-left: 30px;;
float: left;
list-style: none;
}
.nav-login {
list-style-type: none;
float: right;
margin-top: 37px;
margin-right:40px;
color:362c6e;
}
#nav ul li a{
color:blue;
text-decoration:none;
}
#nav.before10 ul li a{
color:blue;
text-decoration:none;
}
#nav.before10 ul li a:hover{
color:grey;
}
#nav.after10{
background:teal;
}
#nav.after10 ul li a{
color:red;
text-decoration:none;
}
#nav.after10 ul li a:hover{
color:white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="nav" class='before10 container-fluid white hidden-xs hidden-sm'>
<ul>
<li class='nav-image-left'><div class='image-container-left'><a href=index><img src='images/ctbig.png' height='62' alt='image-left' /></a></div></li>
<li id="nav-big" class='nav-big'><a href='updating'> About us </a></li>
<li class='nav-more'><a href='updating'> Register new job </a></li>
<li class='nav-more'><a href='updating'> Register business </a></li>
<li class='nav-more'><a href='updating'> Contact us </a></li>
<li class='nav-more'><img src='images/users.png' alt='image-right' width='22' /><a href='updating'> Login </a></li>
<li class='nav-login'>0800 038 6210</li>
</ul>
</div>
I think the problem is how you are trying to set the css properties.
$(".nav-big a:link") selects the actual elements in the DOM tree, nit the corresponding rule in your .css file. Then, when you call ".css("property", "value")" on those elements, you effectively change their element.style property, which is equivalent to setting that property inline (i.e. `).
Since the specificity of inline styles is higher that that of styles defined in a .css file, your :hover rule in a .css file will not be applied anymore.
There isn't really a way to edit you .css files from either JavaScript or JQuery (which is still just a JavaScript library), so what you should do instead is dynamically add and remove classes as described here.
As a side note, you honestly don't need jQuery for such tasks in 2018. It has its uses, but those are all either advanced or obsolete. Loading a external library bloats your page and is overall frowned upon. .ready can be replaced by just placing your <script> tag at the end of the <body>, and others methods now have direct js counterparts. Please consider switching to native js especially if you are still learning the language.

Attempting to add a delay to a Jquery dropdown for a navigation menu

I am attempting to add a delay to this Jquery dropdown. I have tried to use the setTimeout function but this doesn't appear to be working.
I don't know why this isn't working as the delay doesn't happen when I hover over the menu and the submenu drops down immediately. How can I get this to work?
Edit: I'll have to clarify specifically what i want to do. I have a Menu with some submenus. When I hover over the Menu Item, for example 'About', I want a brief delay of 3 seconds before the submenu slides out. Currently, It slides out immediately and this creates an unwanted effect when I quickly move from one Menu item to another. For example, if I move from About to Fees, it shows both submenus at the same time. Basically this is what is happening when I scroll over the menu Items very quickly
https://i.imgur.com/Nv554m9.png
I'm new to Jquery and Javascript and web programming in general, so although I've gone through several similar questions on StackOverFlow, they don't seem to solve my problem. Any assistance will be appreciated.
<script type="text/javascript">
$(document).ready(setTimeout(function() {
$( '.dropdown' ).hover(
function(){
$(this).children('.dropdown-content').slideDown(200);
},
function(){
$(this).children('.dropdown-content').slideUp(0);
}
);
}), 3000);
</script>
EDIT:
This is the HTML of the Menu
<ul id="menu">
<li> Home </li>
<li class="dropdown" >
About
<div class = "dropdown-content">
Background And History
Vision And Mission
Message From the Principal
Message from the Director
Governance
</div>
</li>
<li class="dropdown">
Fees
<div class="dropdown-content">
Primary Fees
Secondary Fees
Admission forms
Fee Policy
</div>
</li>
<li class="dropdown">
Academics
<div class="dropdown-content">
Primary Curriculum
Lower Secondary Curriculum
Upper Secondary Curriculum
Library and ICT Labs
Staff
</div>
</li>
<li class="dropdown">
School&nbspLife
<div class="dropdown-content">
Boarding School
<div class="subdropdown">
Extra Curricular Activities
<div class="subsubmenu">
Sports
Clubs
Entertainment
</div>
</div>
<div class="subdropdown">
Students
<div class="subsubmenu">
Governance
Code of Conduct
Alumni
</div>
</div>
Field Trips
</div>
</li>
<li>
Events
</li>
<li class="dropdown">
News
<div class="dropdown-content">
Notices for Parents
Jobs
</div>
</li>
<li class="dropdown">
Gallery
<div class="dropdown-content">
Sports
Entertainment
Facilities
</div>
</li>
<li class="dropdown">
Contact
<div class="dropdown-content">
FAQ
</div>
</li>
<!--<li>☰</li> -->
</ul>
And the CSS
/*NAVIGATION SECTION*/
nav {
margin: 0px;
}
/*Sets the nav bar in a horizontal manner. Hides the pointers for the list and ensures there's no scroll bar*/
nav ul {
display: flex;
flex-direction:row;
margin: 0;
padding: 0;
list-style-type: none;
overflow: hidden;
border-top: 1px solid #670000;
}
/*Styles each of the individual items in the nav bar list. Adds color and changes their font. Adds a border at the end*/
nav ul li {
flex-grow: 1;
font-family: Constantia,"Lucida Bright",Lucidabright,"Lucida Serif",Lucida,"DejaVu Serif","Bitstream Vera Serif","Liberation Serif",Georgia,serif;
font-size: 15px;
font-weight: bolder;
padding: 0;
}
/*Determines how the links inside the navbar will be displayed.Gives them a background color*/
nav ul li a {
display: block;
background: #800000;
height: 40px;
text-align:center;
padding: 7px 10px;
text-transform: uppercase;
-webkit-transition: 0.45s;
transition: 0.45s;
}
/*Shows how unvisited links will look*/
nav ul li a:link{
text-decoration: none;
color: whitesmoke;
}
/*Changes the color inside visited links*/
nav ul li a:visited {
color: whitesmoke;
margin-left: 60px;
height: 40px;
}
/*Determines what happens when you hover a link*/
nav ul li a:hover{
color: black;
background-color: white;
}
/*Shows what happens a link is active (page you are currently on)*/
nav ul li a.active {
background-color: indianred;
color: white;
}
/*Styles what happens when you hover an active link on an active page*/
nav ul li a.active:hover {
background-color: #990000;
color: white;
}
/*Dropdown stuff*/
.dropdown-content {
display: none;
position: absolute;
color: black;
min-width: 160px;
border-bottom: 0.5px solid deepskyblue;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.subsubmenu {
display: none;
position: absolute;
left: 223px;
top: 25%;
color:black;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
ul li .dropdown-content a:link{
text-decoration: none;
color: whitesmoke;
}
ul li .subsubmenu a:link{
text-decoration: none;
color: black;
}
/*Changes the color inside visited links*/
ul li .dropdown-content a:visited {
color: whitesmoke;
margin-left: 60px;
height: 40px;
}
ul li .subsubmenu a:visited {
color: black;
margin-left: 60px;
height: 40px;
}
.dropdown-content a {
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
font-size: 12px;
background-color: black;
}
.subsubmenu a{
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
font-size: 12px;
background-color: #f9f9f9;
}
.dropdown-content a:hover {
background-color: #990000;
}
.subsubmenu a:hover {
background-color: #990000;
}
/*
.dropdown:hover .dropdown-content {
display: block;
color: whitesmoke;
} */
.subdropdown:hover .subsubmenu {
display: block;
color: whitesmoke;
}
$(document).ready(setTimeout(function(){}, 3000)) does not delay .slideDown() call at each event dispatched by .hover(); rather, delays call of function passed to setTimeout() at .ready() call for 3000.
You can use .delay(). Also call .clearQueue() chained to $(this).children('.dropdown-content') at function passed to second parameter of .hover() to clear the element queue of .slideDown() call at first parameter.
$(document).ready(function() {
$('.dropdown').hover(
function() {
$(this).children('.dropdown-content')
.delay(1000) // set duration of delay in milliseconds here
.slideDown(200);
},
function() {
$(this).children('.dropdown-content')
.clearQueue()
.slideUp(0);
})
});
/*NAVIGATION SECTION*/
nav {
margin: 0px;
}
/*Sets the nav bar in a horizontal manner. Hides the pointers for the list and ensures there's no scroll bar*/
nav ul {
display: flex;
flex-direction: row;
margin: 0;
padding: 0;
list-style-type: none;
overflow: hidden;
border-top: 1px solid #670000;
}
/*Styles each of the individual items in the nav bar list. Adds color and changes their font. Adds a border at the end*/
nav ul li {
flex-grow: 1;
font-family: Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Bitstream Vera Serif", "Liberation Serif", Georgia, serif;
font-size: 15px;
font-weight: bolder;
padding: 0;
}
/*Determines how the links inside the navbar will be displayed.Gives them a background color*/
nav ul li a {
display: block;
background: #800000;
height: 40px;
text-align: center;
padding: 7px 10px;
text-transform: uppercase;
-webkit-transition: 0.45s;
transition: 0.45s;
}
/*Shows how unvisited links will look*/
nav ul li a:link {
text-decoration: none;
color: whitesmoke;
}
/*Changes the color inside visited links*/
nav ul li a:visited {
color: whitesmoke;
margin-left: 60px;
height: 40px;
}
/*Determines what happens when you hover a link*/
nav ul li a:hover {
color: black;
background-color: white;
}
/*Shows what happens a link is active (page you are currently on)*/
nav ul li a.active {
background-color: indianred;
color: white;
}
/*Styles what happens when you hover an active link on an active page*/
nav ul li a.active:hover {
background-color: #990000;
color: white;
}
/*Dropdown stuff*/
.dropdown-content {
display: none;
position: absolute;
color: black;
min-width: 160px;
border-bottom: 0.5px solid deepskyblue;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.subsubmenu {
display: none;
position: absolute;
left: 223px;
top: 25%;
color: black;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
ul li .dropdown-content a:link {
text-decoration: none;
color: whitesmoke;
}
ul li .subsubmenu a:link {
text-decoration: none;
color: black;
}
/*Changes the color inside visited links*/
ul li .dropdown-content a:visited {
color: whitesmoke;
margin-left: 60px;
height: 40px;
}
ul li .subsubmenu a:visited {
color: black;
margin-left: 60px;
height: 40px;
}
.dropdown-content a {
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
font-size: 12px;
background-color: black;
}
.subsubmenu a {
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
font-size: 12px;
background-color: #f9f9f9;
}
.dropdown-content a:hover {
background-color: #990000;
}
.subsubmenu a:hover {
background-color: #990000;
}
/*
.dropdown:hover .dropdown-content {
display: block;
color: whitesmoke;
} */
.subdropdown:hover .subsubmenu {
display: block;
color: whitesmoke;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="menu">
<li> Home </li>
<li class="dropdown">
About
<div class="dropdown-content">
Background And History
Vision And Mission
Message From the Principal
Message from the Director
Governance
</div>
</li>
<li class="dropdown">
Fees
<div class="dropdown-content">
Primary Fees
Secondary Fees
Admission forms
Fee Policy
</div>
</li>
<li class="dropdown">
Academics
<div class="dropdown-content">
Primary Curriculum
Lower Secondary Curriculum
Upper Secondary Curriculum
Library and ICT Labs
Staff
</div>
</li>
<li class="dropdown">
School&nbspLife
<div class="dropdown-content">
Boarding School
<div class="subdropdown">
Extra Curricular Activities
<div class="subsubmenu">
Sports
Clubs
Entertainment
</div>
</div>
<div class="subdropdown">
Students
<div class="subsubmenu">
Governance
Code of Conduct
Alumni
</div>
</div>
Field Trips
</div>
</li>
<li>
Events
</li>
<li class="dropdown">
News
<div class="dropdown-content">
Notices for Parents
Jobs
</div>
</li>
<li class="dropdown">
Gallery
<div class="dropdown-content">
Sports
Entertainment
Facilities
</div>
</li>
<li class="dropdown">
Contact
<div class="dropdown-content">
FAQ
</div>
</li>
<!--<li>☰</li> -->
</ul>
if you are trying delay after simple page load and without any other event call then pull out your slidedown statement from settimeout
<script type="text/javascript">
$(document).ready(function(){
setTimeout(function(){
$('dropdown').children('.dropdown-content').slideDown(200);
}, 3000)
});
</script>
However if you want on hover then settimeout should be called on hover.
$(function(){
function hoverMe(){
$('dropdown').children('.dropdown-content').slideDown(200);
}
$(".dropdown").on('hover', function(){
setTimeout(hoverMe, 100);
})
})
Also jquery.ready function takes a function definition but you are calling setimeout there instead you should wrap your setimeout in a anonymous function

How to remove blue-ish outline in navigation bar?

A few hours back I asked a question on how my background disappeared when i added a collapsible list. The solution they gave me was:
body.ui-overlay-a {
background-color: #dc143c;
}
div.ui-page-theme-a {
background-color: transparent;
}
I asked the same person about the blue box and he gave me this:
div.ui-page-theme-a {
background-color: transparent;
}
But this didn't work does anyone have any answers?
Navigation bar code (CSS):
/* Navigation bar */
.nav {
font-family: 'Roboto', sans-serif;
margin-top: 20px;
height: 40px;
background: #000000;
}
.nav ul {
margin: 0;
padding: 0;
}
.nav ul li {
list-style: none;
}
.nav ul li a {
text-decoration: none;
float: right;
display: block;
padding: 10px 50px;
color: white;
}
.nav ul li a:hover {
color: #D3D3D3;
}
.headerBreak {
width: 100%;
height: 0;
border-bottom: 2px solid #000000;
}
h4 {
font-family: 'Roboto', sans-serif;
font-size: 24px;
text-align: right;
text-decoration: none;
}
p {
font-family: 'Lato', sans-serif;
font-size: 30px;
}
And this is the content inside the navigation bar (inside )
<div class="nav">
<ul>
<li>Contacts</li>
<li>Map</li>
<li>Reservations</li>
<li>Online Order</li>
<li>Menu</li>
<li>About</li>
<li>Home</li>
</ul>
</div>
<div class="headerBreak"></div>
Note that this does not only apply to the navigation bar but also applies to my and
Reference: http://i.imgur.com/acnJE5Y.png
Edit 1: I added this website to a free domain hoster, I have also added outline: none; to nav ul li a { but it still doesnt work when i open itbut when I duplicate the file and I open it the text does not have the blue outline, but in my original file it does
http://marcxu88.000webhostapp.com
If you could inspect the code and see if what is wrong it would be greatly appreciated.
Thanks in advance.
Try adding outline: none; to the selector .nav ul li a.

How do I create a drop down menu without nested lists?

I am trying to achieve a basic css drop down menu with NO nested lists within lists. In other words the normal way is:
<ul>
<li><a>Blah</a></li>
<li><a>Blah Parent</a>
<ul>
<li><a>Blah Child</a></li>
</ul>
</li>
</ul>
The way that I need to do it is:
<ul>
<li><a>Blah</a></li>
<li><a>Blah Parent</a></li>
<li class="childitem"><a>Blah Parent</a><li>
<li class="childitem"><a>Blah Parent</a><li>
<li><a>Blah</a></li>
<li><a>Blah</a></li>
<li class="childitem"><a>Blah Parent</a><li>
<li class="childitem"><a>Blah Parent</a><li>
</ul>
Is there any way to do this with purely css? Or with some basic js help?
The result you want is actually a bit ambiguous, but there are several approaches to this.
Solution 1 - change the DOM
If you want to change the DOM dynamically you can make use of jQuery's nextUntil() to find the sibling elements to move:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/9afavum5/
// Solution 1 - change the DOM
$("ul li:not(.childitem)").each(function () {
var children = $(this).nextUntil(":not(.childitem)");
if (children.length) {
$(this).append($("<ul>").append(children));
}
});
This works by finding the intended parents (that do :not have .childitem), then finding the siblings up until the next parent element using nextUntil.
Soution 2 - toggle existing
If you simply want to toggle to child items, and not change the DOM, you can use similar matching techniques to find the sibling items:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/9afavum5/1/
// Solution 2 - toggle the siblings
$("ul li.childitem").hide();
$("ul li:not(.childitem)").click(function(){
$(this).nextUntil(":not(.childitem)").toggle();
});
Indeed, "with some basic js help", you'd need just a simple 'one-liner' (in your function) to fix up the HTML, here it is formatted for better readability (and explanation in comments):
function nestSubULbyClass(par, cls){
for( var elms=par.getElementsByTagName('li'), L=elms.length, t
; L-- //loop through elements in reverse to avoid nested look-ahead loop(s)
; ~(' '+elms[L].className+' ').indexOf(cls) //if current elm contains specified class
? (t || (t=document.createElement('ul')) //then take temp UL or create a new one
).appendChild(par.removeChild(elms[L])) // and move current elm to temp UL
: t && (elms[L].appendChild(t), t=0) //else append temp UL to current elm
); // and clear temp with falsy value
}
//"Make it so, number one!!" Note this is just an example, hook and pass UL any way you like
window.onload=function(){
nestSubULbyClass(document.getElementsByTagName('ul')[0], 'childitem');
};
<ul>
<li><a>Blah</a></li>
<li><a>Blah Parent</a></li>
<li class="childitem"><a>Blah Parent</a></li>
<li class="childitem"><a>Blah Parent</a></li>
<li><a>Blah</a></li>
<li><a>Blah</a></li>
<li class="childitem"><a>Blah Parent</a></li>
<li class="childitem"><a>Blah Parent</a></li>
</ul>
EDIT:
From here on, one can now simply use any pure css based drop-down menu (and styling) without requiring any other javascript-handlers (nice)!
For the following example I used the css from this answer. Note: I removed comments and formatting from the one-liner (humoring anyone arguing that non-context-aware standard formatting is better to read ☺)
function nestSubULbyClass(par, cls) {
for(var elms=par.getElementsByTagName('li'), L=elms.length, t; L--; ~(' '+elms[L].className+' ').indexOf(cls) ? (t || (t=document.createElement('ul'))).appendChild(par.removeChild(elms[L])) : t && (elms[L].appendChild(t), t=0));
}
window.onload=function(){
nestSubULbyClass(document.getElementsByTagName('ul')[0], 'childitem');
};
ul {
font-family: Arial, Verdana;
font-size: 14px;
margin: 0;
padding: 0;
list-style: none;
}
ul li {
display: block;
position: relative;
float: left;
}
li ul {
display: none;
}
ul li a {
display: block;
text-decoration: none;
color: #ffffff;
border-top: 1px solid #ffffff;
padding: 5px 15px 5px 15px;
background: #2C5463;
margin-left: 1px;
white-space: nowrap;
}
ul li a:hover {
background: #617F8A;
}
li:hover ul {
display: block;
position: absolute;
}
li:hover li {
float: none;
font-size: 11px;
}
li:hover a {
background: #617F8A;
}
li:hover li a:hover {
background: #95A9B1;
}
<ul>
<li><a>Blah</a></li>
<li><a>Blah Parent</a></li>
<li class="childitem"><a>Blah Parent</a></li>
<li class="childitem"><a>Blah Parent</a></li>
<li><a>Blah</a></li>
<li><a>Blah</a></li>
<li class="childitem"><a>Blah Parent</a></li>
<li class="childitem"><a>Blah Parent</a></li>
</ul>
You can As Long as The Got Id's And Clases FIDDLE HERE
HERE
<ul>
<li><a>Blah</a></li>
<li class="drp"><a>Blah Parent</a></li>
<li class="childitem"><a>Blah Parent</a><li>
<li class="childitem"><a>Blah Parent</a><li>
</ul>
JS
$(document).ready(function(){
$(".drp").hover(function(){
$(".childitem").slideToggle("fast");
},function(){
$(".childitem").hide();
});
$(".childitem").hover(function(){
$(".childitem").show();
},function(){
$(".childitem").hide();
});
});
CSS
.drp:hover
{
cursor: pointer;
}
ul li
{
list-style-type: none;
}
.childitem
{
display: none;
}
.childitem:hover
{
background: green;
cursor: pointer;
}
Here is an example which uses CSS and a javascript.
<div class="topnav" id="myTopnav">
Home
<div class="dropdown">
<button class="dropbtn">Products
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
<div class="dropdown">
<button class="dropbtn">Services
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
Link 1
Link 2
Link 3
</div>
</div>
About
News
Contact
☰
</div>
Here is the javascript:
<script>
function myFunction() {
var x = document.getElementById("myTopnav");
if (!x.classList.contains("responsive")) {
x.classList.add("responsive");
} else {
x.classList.remove("responsive");
}
}
</script>
and the CSS
.topnav {
background-color: #333;
overflow: ;
}
.topnav::after {
clear: both;
content: "";
display: block;
}
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
.active {
background-color: ;
color: white;
}
.topnav .icon {
display: none;
}
.dropdown {
float: left;
overflow: ;
}
.dropdown .dropbtn {
font-size: 17px;
border: none;
outline: none;
color: white;
padding: 14px 16px;
background-color: #333;
font-family: inherit;
margin: 0;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
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;
}
.topnav a:hover, .dropdown:hover .dropbtn {
background-color: #555;
color: white;
}
.dropdown-content a:hover {
background-color: #ddd;
color: black;
}
.dropdown:hover .dropdown-content {
display: block;
}
#media screen and (max-width: 600px) {
.topnav a:not(:first-child), .dropdown .dropbtn {
display: none;
}
.topnav a.icon {
float: right;
display: block;
}
}
#media screen and (max-width: 600px) {
.topnav.responsive {position: relative;}
.topnav.responsive .icon {
position: absolute;
right: 0;
top: 0;
}
.topnav.responsive a {
float: none;
display: block;
text-align: left;
}
.topnav.responsive .dropdown {float: none;}
.topnav.responsive .dropdown-content {position: relative;}
.topnav.responsive .dropdown .dropbtn {
display: block;
width: 100%;
text-align: left;
}
}

How to make a dynamic accordion menu with jQuery

Lets say I have the following menu structure. I have 3 problems with it.
$('.parent ul').hide();
var current_parent;
$(document).delegate('.parent', 'click', (function() {
var $this = $(this);
if(current_parent !== undefined) {
current_parent.find('ul').slideUp();
}
current_parent = $this;
// Check if the element is visble or not
if(!$this.find('ul').is(':visible')) {
$this.find('ul').slideDown();
} else {
$this.find('ul').slideUp();
}
}));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li class="parent">menu item1
<ul>
<li class="child">Sub menu item1</li>
<li class="child parent">Sub menu item2
<ul>
<li class="child">Sub-sub menu item1</li>
</ul>
</li>
</ul>
</li>
<li class="parent">menu item2
<ul>
<li class="child">Sub menu item3</li>
</ul>
</li>
</ul>
When you click on menu item 1 the Sub-sub menu item1 is also
opened. How can this be prefented?;
When you click on Sub menu item2 the menu item1 is also closed. How can this be prefented?.
How can I make this more dynamic so that when I add deeper menu items the menu still works but without having to add things like: $('ul ul ul').slideDown(); etc.?
Could anyone help me with these problems?
Thanks in advance
You can create a drop drop down menu with jquery
I have given individual HTML, CSS and JQuery code, use it and try to understand it.
There is an outer <div id="navigation"> and inside it their is annow in it everyis main menu item andin everyis sub menu item. Furthermore you can create sub menu in sub menu also by creatingin`.
$(document).ready(function () {
$("li").click(function () {
var x = $(this).children("a:first").attr("href");
if (x != undefined)
window.location.href = x;
});
$("#nav li").hover(function () {
$(this).find("ul:first").css({
visibility: "visible",
display: "none",
}).slideDown(400);
}, function () {
$(this).find("ul:first").css({ visibility: "hidden" });
});
});
body {
font-family: Calibri, Verdana;
font-size: 16px;
color: white;
}
a {
color: inherit;
text-decoration: none;
}
#navigation {
height: 40px;
}
#nav {
list-style: none;
margin: 0px;
padding: 0px;
}
#nav ul {
list-style: none;
margin: 10px 0px 0px -5px;
padding: 0px;
display: none;
}
#nav li {
float: left;
width: 150px;
height: 30px;
padding: 10px 0px 0px 5px;
border: 0px solid transparent;
border-right-width: 1px;
border-right-color: gray;
background-color: #6397CB;
}
#nav li ul li {
width: 145px;
height: 22px;
padding: 10px 0px 8px 10px;
border: 0px solid transparent;
border-top-width: 1px;
border-top-color: gray;
}
#nav li ul li ul {
position: relative;
top: -40px;
margin-left: 145px;
color: white;
}
#nav li ul li ul li {
border: 0px solid transparent;
border-left-width: 1px;
border-left-color: gray;
border-top-width: 1px;
border-top-color: gray;
}
#nav li:hover {
background-color: lightgray;
cursor: pointer;
}
#nav li ul li:hover {
color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navigation">
<ul id="nav">
<li>My Name</li>
<li>About U
<ul>
<li>How U?
<ul>
<li>Your Extras</li>
</ul>
</li>
<li>Howz U?</li>
</ul>
</li>
<li>More</li>
</ul>
</div>

Categories

Resources