js
const navItems = document.querySelectorAll('.navbar__items')
const dropDown = document.querySelectorAll('.dropdown')
dropDown.forEach(element => {
element.addEventListener('click',()=>{
{
navItems.forEach(nav =>{
nav.classList.toggle('drop')
})
}
})
})
HTML
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
</ul>
CSS
.navbar{
position: relative;
}
.navbar__items{
position: absolute;
display: none;
}
.drop{
display: block;
}
I have a navbar and each of these navbar items have dropdown items. I want to show these dropdown items when I click on the 'dropdown' class. But the problem is when I click on one of them all the dropdowns are visible. How do I show only the list I've clicked on?
Enter the below code
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<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: 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;}
</style>
</head>
<body>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Click</button>
<div id="myDropdown" class="dropdown-content">
Clicked
Clicked
Clicked
</div>
</div>
<script>
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
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>
</html>
As mentioned in comments it is better to use Event Delegation technique.
The algorithm is quite simple:
Add listener on the parent element
On click check if dropdown-opener was clicked
Get drop-down which I need to open
Close other dropdowns
Open dropdown from 3.
const allDropdowns = document.querySelectorAll('.navbar__items')
const DROP_CLASS = 'drop';
const navbar = document.querySelector('.navbar');
navbar.addEventListener('click', ({target}) => {
if (!target.classList.contains('dropdown')) return;
const parent = target.parentNode;
const navItems = parent
.querySelector('.navbar__items');
allDropdowns.forEach(el => el !== navItems && el.classList.remove(DROP_CLASS));
if (navItems) {
navItems.classList.toggle(DROP_CLASS);
}
});
.navbar{
position: relative;
}
.navbar__items{
position: absolute;
left: 80px;
display: none;
}
.drop{
display: block;
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
</ul>
Use the event target to get the parentNode, then use the parentNode to query the hidden element as all your elements are grouped in the same parent/child grouping. Also you can set an initial class for hidden, display: none; in each element and add it on click. A forEach loop sets each elements display to none using the hidden class on click.
const navItems = document.querySelectorAll('.navbar__items')
const dropDown = document.querySelectorAll('.dropdown')
// callback function that passes in the event => e from your listener
function showDropdown (e){
// set each navbar__items element display: none using hidden class
navItems.forEach(el => el.classList.add('hidden'))
// query the specific .navbar__items in the event.targets group
let dd = e.target.parentNode.querySelector('.navbar__items')
// remove the hidden class a nd show the dropdown for this event.target
dd.classList.remove('hidden')
}
// iterate over the dropdown element
dropDown.forEach(element => {
// function showDropdown on click
element.addEventListener('click', showDropdown)
})
.navbar {
position: relative;
}
.navbar__items {
position: absolute;
left: 75px;
}
.hidden {
display: none;
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li>clicked 1</li>
<li>clicked 1</li>
<li>clicked 1</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li>clicked 2</li>
<li>clicked 2</li>
<li>clicked 2</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li>clicked 3</li>
<li>clicked 3</li>
<li>clicked 3</li>
</ul>
</li>
</ul>
Rather than using addEventlistener you should add onclick method in html to every drop-down with same method name but change the ul class name with for each drop-down and then pass class name in method and then toggle the drop-down with parameter class name.
For example,
function onClick(item) {
if (document.getElementsByClassName(item).classList.contains('hidden')) {
document.getElementsByClassName('dropdown').classList.remove('hidden');
}
if (!document.getElementsByClassName(item)[0].classList.contains('hidden')) {
document.getElementsByClassName('dropdown').classList.add('hidden');
}
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items1')">click</div>
<ul class="navbar__items1 hidden">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items2')">click</div>
<ul class="navbar__items2 hidden">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items3')">click</div>
<ul class="navbar__items3 hidden">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
</ul>
Related
I have made a website with a navigation menu, there are also two dropdown menus, I have also placed 2 font awesome icons arrows on each of the dropdowns, but I am unsure how to make them rotate on when clicking the dropdown menus. I would like them to rotate 90 degrees down. I have already made the classes for the sub menus,
let click = document.querySelector('.click');
let list = document.querySelector('.Sub-menu-1');
click.addEventListener("click", () => {
list.classList.toggle('NewSub-menu-1');
});
let click2 = document.querySelector('.click2');
let list2 = document.querySelector('.Sub-menu-2');
click2.addEventListener("click", () => {
list2.classList.toggle('NewSub-menu-2');
});
.nav-Links ul li .Sub-menu-1 ul li,
.nav-Links ul li .Sub-menu-2 ul li {
width: 110px;
padding: 5px;
background: transparent;
border-radius: 0;
text-align: left;
}
.fas.fa-chevron-left {
display: inline-block;
padding-left: 5px;
}
<div class="nav-Links" id="navLinks">
<i class="fas fa-times" onclick="hideMenu()"></i>
<ul>
<li> Home </li>
<li> About Us </li>
<li class="click2">
Recruiting <span class="fas fa-chevron-left"></span>
<div class="Sub-menu-2">
<ul>
<li>Number 1</li>
<li>Number 2</li>
</ul>
</div>
</li>
<li> Contact Us </li>
<li> Leave Request </li>
<li class="click"> CadetLinks <span class="fas fa-chevron-left"></span>
<div id="navLinks1" class="Sub-menu-1">
<ul>
<li>Number 1</li>
<li>Number 2</li>
<li>Number 3</li>
</ul>
</div>
</li>
</ul>
</div>
You can try this
list.onclick=function(){
list.style.transform="rotate(90deg)";
}
list2.onclick=function(){
list2.style.transform="rotate(90deg)";
}
Just used another icon but you can get the idea:
let click = document.querySelector('.click');
let list = document.querySelector('.Sub-menu-1');
click.addEventListener("click", () => {
list.classList.toggle('NewSub-menu-1');
document.querySelector('.click .flaticon-hand-10').classList.toggle('gly');
});
let click2 = document.querySelector('.click2');
let list2 = document.querySelector('.Sub-menu-2');
click2.addEventListener("click", () => {
list2.classList.toggle('NewSub-menu-2');
document.querySelector('.click2 .flaticon-hand-10').classList.toggle('gly');
});
.nav-Links ul li .Sub-menu-1 ul li,
.nav-Links ul li .Sub-menu-2 ul li {
width: 110px;
padding: 5px;
background: transparent;
border-radius: 0;
text-align: left;
}
.fas.fa-chevron-left {
display: inline-block;
padding-left: 5px;
}
#font-face {
font-family: 'Flaticon';
src: url('data:font/ttf;base64,AAEAAAANAIAAAwBQRkZUTWzLl7IAAAV4AAAAHEdERUYAMQAGAAAFWAAAACBPUy8yL7pL5QAAAVgAAABWY21hcMARI74AAAHAAAABSmdhc3D//wADAAAFUAAAAAhnbHlmwP2S0wAAAxgAAABwaGVhZARhaP0AAADcAAAANmhoZWED0gHFAAABFAAAACRobXR4BgAAHgAAAbAAAAAQbG9jYQA4AAAAAAMMAAAACm1heHAARwAoAAABOAAAACBuYW1liNt9UwAAA4gAAAGScG9zdJJ3apwAAAUcAAAAMQABAAAAAQAAIRWaJV8PPPUACwIAAAAAANGhFEAAAAAA0aEUQAAe/8AB4gHAAAAACAACAAAAAAAAAAEAAAHA/8AALgIAAAAAAAHiAAEAAAAAAAAAAAAAAAAAAAAEAAEAAAAEACUAAQAAAAAAAgAAAAEAAQAAAEAAAAAAAAAAAQIAAZAABQAIAUwBZgAAAEcBTAFmAAAA9QAZAIQAAAIABQkAAAAAAAAAAAAAEAAAAAAAAAAAAAAAUGZFZABA4ADgAAHA/8AALgHAAEAAAAABAAAAAAAAAgAAAAAAAAACAAAAAgAAHgAAAAMAAAADAAAAHAABAAAAAABEAAMAAQAAABwABAAoAAAABgAEAAEAAgAA4AD//wAAAADgAP//AAAgAwABAAAAAAAAAAABBgAAAQAAAAAAAAABAgAAAAIAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAEAHv/AAeIBwAAkAAAlIgcuASMiBy4BIyIHNTQmIgYdAScuAQ4BHwEeATsBMjY9ATQmAa0ODQMdExANBRsRDgwfLB8SDyshAg5zEjYYcS9CH9sHEhgIDxMIexYfHxbtFRADHSwQgRIaOyqBFh8AAAAAAAwAlgABAAAAAAABAAgAEgABAAAAAAACAAcAKwABAAAAAAADACQAfQABAAAAAAAEAAgAtAABAAAAAAAFAAsA1QABAAAAAAAGAAgA8wADAAEECQABABAAAAADAAEECQACAA4AGwADAAEECQADAEgAMwADAAEECQAEABAAogADAAEECQAFABYAvQADAAEECQAGABAA4QBmAGwAYQB0AGkAYwBvAG4AAGZsYXRpY29uAABSAGUAZwB1AGwAYQByAABSZWd1bGFyAABGAG8AbgB0AEYAbwByAGcAZQAgADIALgAwACAAOgAgAGYAbABhAHQAaQBjAG8AbgAgADoAIAAxADMALQA2AC0AMgAwADEANQAARm9udEZvcmdlIDIuMCA6IGZsYXRpY29uIDogMTMtNi0yMDE1AABmAGwAYQB0AGkAYwBvAG4AAGZsYXRpY29uAABWAGUAcgBzAGkAbwBuACAAMQAuADAAAFZlcnNpb24gMS4wAABmAGwAYQB0AGkAYwBvAG4AAGZsYXRpY29uAAAAAAIAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAABAAAAAEAAgECBmhhbmQxMAAAAAAAAAH//wACAAEAAAAOAAAAGAAAAAAAAgABAAMAAwABAAQAAAACAAAAAAABAAAAAMmJbzEAAAAA0aEUQAAAAADRoRRA') format('truetype');
font-weight: normal;
font-style: normal;
}
[class^="flaticon-"]:before,
[class*=" flaticon-"]:before,
[class^="flaticon-"]:after,
[class*=" flaticon-"]:after {
font-family: Flaticon;
font-size: 20px;
font-style: normal;
margin-left: 20px;
}
.flaticon-hand-10:before {
content: "\e000";
}
li > i {
transition: all .2s ease;
}
.gly {
filter: progid: DXImageTransform.Microsoft.BasicImage(rotation=0.5);
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-o-transform: rotate(90deg);
transform: rotate(90deg);
display: inline-block;
}
<div>
<ul>
<li class="click2">
Recruiting
<i class="flaticon-hand-10"></i>
<div class="Sub-menu-2">
<ul>
<li>Number 1</li>
<li>Number 2</li>
</ul>
</div>
</li>
<li> Contact Us </li>
<li> Leave Request </li>
<li class="click"> CadetLinks
<i class="flaticon-hand-10"></i>
<div id="navLinks1" class="Sub-menu-1">
<ul>
<li>Number 1</li>
<li>Number 2</li>
<li>Number 3</li>
</ul>
</div>
</li>
</ul>
</div>
Try this. The transform is done on hover but you can use different events.
.nav-Links ul li .Sub-menu-1 ul li,
.nav-Links ul li .Sub-menu-2 ul li {
width: 110px;
padding: 5px;
background: transparent;
border-radius: 0;
text-align: left;
}
.fas.fa-chevron-left {
display: inline-block;
padding-left: 5px;
}
.link-icon{
transition:2s;
}
.link-icon:hover{
-o-transform:rotate(-90deg);
-ms-transform:rotate(-90deg);
-moz-transform:rotate(-90deg);
-webkit-transform:rotate(-90deg);
transform:rotate(-90deg);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<ul>
<li> Home </li>
<li> About Us </li>
<li class="click2">
Recruiting <span class="link-icon fas fa-chevron-left"></span>
<div class="Sub-menu-2">
<ul>
<li>Number 1</li>
<li>Number 2</li>
</ul>
</div>
</li>
<li> Contact Us </li>
<li> Leave Request </li>
<li class="click"> CadetLinks <span class="fas fa-chevron-left"></span>
<div id="navLinks1" class="Sub-menu-1">
<ul>
<li>Number 1</li>
<li>Number 2</li>
<li>Number 3</li>
</ul>
</div>
</li>
</ul>
</div>
I have three navigations in one page and I'm trying to show the active links for each nav. For some reason the third nav isn't working correctly. For example, if you click on "chapter 2" or "chapter 3" or "chapter 4", "chapter 1" stays active. I don't know if it's because "Chapter 1" and "sublink4" from the middle nav have the same url. I tried removing the active class of the third nav, but it's not working. Unfortunately the snipping isn't working as it is on my computer. I only used target="_blank" on the snippet, not only my local machine since you can't click on links on the snippet without restarting the snippet.Thanks
$(window).on('load', function () {
$('body').setActiveMenuItem();
$('body').setActiveMenuItem2();
$('body').setActiveMenuItem3();
});
$(document).ready(function () {
//first nav
$.fn.setActiveMenuItem2 = function () {
$.each($('.nav1').find('li'), function () {
$(this).toggleClass('active',
window.location.pathname.indexOf($(this).find('a').attr('href')) > -1);
});
}
//middle nav
$.fn.setActiveMenuItem3 = function () {
$.each($('.nav3').find('li'), function () {
$(this).toggleClass('active3',
window.location.pathname.indexOf($(this).find('a').attr('href')) > -1);
});
}
//third nav
$.fn.setActiveMenuItem = function () {
$.each($('.nav2').find('li'), function () {
$(this).removeClass('active2');
$(this).toggleClass('active2',
window.location.pathname.indexOf($(this).find('a').attr('href')) > -1);
});
}
});
li.active {
background-color: red;
}
li.active2 {
background-color: blue;
}
li.active {
background-color: yellow;
}
.nav1 ul, .nav3 ul {
display: flex;
justify-content: space-between;
}
nav {
margin-bottom: 50px;
}
.wrapper {
width: 400px;
margin: auto;
}
li {
list-style: none;
background-color: aliceblue;
padding: 10px;
}
li a {
padding: 10px;
}
li a:hover {
color: red;
background: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<nav class="nav1">
<ul>
<li> Link 1 </li>
<li><a href="/link-2" target="_blank" >Link 2</a> </li>
<li>Link 3 </li>
<li>Link 4 </li>
</ul>
</nav>
<nav class="nav3">
<ul>
<li>Subink 1</li>
<li>Subink 2</li>
<li>Subink 3</li>
</ul>
</nav>
<nav class="nav2">
<ul>
<li>Chapter 1</li>
<li>Chapter 2</li>
<li>Chapter 3</li>
</ul>
</nav>
</div>
-> replace $ to j Query
->Either replace a latest jquery
Use preventDefault to let default event handler to open new link.
window.open() will let you open links in new tabs.
Note: This code won't work in sand-boxes.
Let me know if I'm missing something?
var links = document.querySelectorAll('a');
links.forEach((node) => {
node.addEventListener("click", (evt) => {
evt.stopPropagation();
evt.preventDefault();
evt.target.classList.add('active');
window.open(evt.target.href);
});
});
li.active {
background-color: red;
}
li.active2 {
background-color: blue;
}
li.active {
background-color: yellow;
}
.nav1 ul,
.nav3 ul {
display: flex;
justify-content: space-between;
}
nav {
margin-bottom: 50px;
}
.wrapper {
width: 400px;
margin: auto;
}
li {
list-style: none;
background-color: aliceblue;
padding: 10px;
}
li a {
padding: 10px;
}
li a:hover {
color: red;
background: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<nav class="nav1">
<ul>
<li> Link 1 </li>
<li>Link 2 </li>
<li>Link 3 </li>
<li>Link 4 </li>
</ul>
</nav>
<nav class="nav3">
<ul>
<li>Subink 1</li>
<li>Subink 2</li>
<li>Subink 3</li>
</ul>
</nav>
<nav class="nav2">
<ul>
<li>Chapter 1</li>
<li>Chapter 2</li>
<li>Chapter 3</li>
</ul>
</nav>
</div>
I did the "expand/collapse all" function, everything is working well, except the arrow. It doesn't pointing to the correct direction. I'm not sure how to do that, so I leave it empty on my code. My issue is shown below.
(Red box represents the click action)
Click "View all", can see the expanders are opened. The arrows pointing down.
Click "A" to collapse the expander, and the arrow pointing up.
Click "Collapse all", the expanders are collpased. Now you can see my problem, "A" arrow is pointing up and the rest are pointing down.
Hoping that some of you could provide me with some advice. Thanks!
$(".aq_epdtitle").click(function() {
$('.aq_expandct').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".aq_epdtitle1").click(function() {
$('.aq_expandct1').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".aq_epdtitle2").click(function() {
$('.aq_expandct2').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".expandall").click(function() {
$('.aq_expandct').slideDown().toggleClass('active');
$('.aq_expandct1').slideDown().toggleClass('active');
$('.aq_expandct2').slideDown().toggleClass('active');
});
$(".collapseall").click(function() {
$('.aq_expandct').slideUp().removeClass('active');
$('.aq_expandct1').slideUp().removeClass('active');
$('.aq_expandct2').slideUp().removeClass('active');
});
ul { list-style-type: none; margin:0; padding: 0; }
.eservices_left ul li{display:inline;}
.aq_expandct, .aq_expandct1, .aq_expandct2 {
display: none;
padding : 5px;
}
.aq_epdtitle, .aq_epdtitle1, .aq_epdtitle2{
background:#ccc url('https://image.ibb.co/jUyN5Q/arrow_up_grey.png') no-repeat;
background-position:right 0px;
cursor:pointer;
padding: 0 10px;
margin: 10px 0;
}
.collapsed .aq_epdtitle, .collapsed .aq_epdtitle1, .collapsed .aq_epdtitle2{
background-image:url('https://image.ibb.co/d669kQ/arrow_down_grey.png');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="expandall">View all</div>
<div class="collapseall">Collapse all</div>
<ul>
<li class="mobexpand collapsed">
<div class="aq_epdtitle">A</div>
<ul class="aq_expandct">
<li>A1</li>
<li>A2</li>
</ul>
</li>
<li class="mobexpand collapsed">
<div class="aq_epdtitle1">B</div>
<ul class="aq_expandct1">
<li>B1</li>
<li>B2</li>
</ul>
</li>
<li class="mobexpand collapsed noborder">
<div class="aq_epdtitle2">C</div>
<ul class="aq_expandct2">
<li>C1</li>
<li>C2</li>
</ul>
</li>
</ul>
Just add $('.mobexpand').addClass('collapsed'); ($(".expandall").click) in show all function
and $('.mobexpand').removeClass('collapsed'); ($(".collapseall").click) and in collsapse all function as bellow
$(".aq_epdtitle").click(function() {
$('.aq_expandct').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".aq_epdtitle1").click(function() {
$('.aq_expandct1').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".aq_epdtitle2").click(function() {
$('.aq_expandct2').slideToggle().toggleClass('active');
$(this).closest('.mobexpand').toggleClass('collapsed');
});
$(".expandall").click(function() {
$('.aq_expandct').slideDown().toggleClass('active');
$('.aq_expandct1').slideDown().toggleClass('active');
$('.aq_expandct2').slideDown().toggleClass('active');
$('.mobexpand').removeClass('collapsed');
});
$(".collapseall").click(function() {
$('.aq_expandct').slideUp().removeClass('active');
$('.aq_expandct1').slideUp().removeClass('active');
$('.aq_expandct2').slideUp().removeClass('active');
$('.mobexpand').addClass('collapsed');
});
ul { list-style-type: none; margin:0; padding: 0; }
.eservices_left ul li{display:inline;}
.aq_expandct, .aq_expandct1, .aq_expandct2 {
display: none;
padding : 5px;
}
.aq_epdtitle, .aq_epdtitle1, .aq_epdtitle2{
background:#ccc url('https://image.ibb.co/jUyN5Q/arrow_up_grey.png') no-repeat;
background-position:right 0px;
cursor:pointer;
padding: 0 10px;
margin: 10px 0;
}
.collapsed .aq_epdtitle, .collapsed .aq_epdtitle1, .collapsed .aq_epdtitle2{
background-image:url('https://image.ibb.co/d669kQ/arrow_down_grey.png');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="expandall">View all</div>
<div class="collapseall">Collapse all</div>
<ul>
<li class="mobexpand collapsed">
<div class="aq_epdtitle">A</div>
<ul class="aq_expandct">
<li>A1</li>
<li>A2</li>
</ul>
</li>
<li class="mobexpand collapsed">
<div class="aq_epdtitle1">B</div>
<ul class="aq_expandct1">
<li>B1</li>
<li>B2</li>
</ul>
</li>
<li class="mobexpand collapsed noborder">
<div class="aq_epdtitle2">C</div>
<ul class="aq_expandct2">
<li>C1</li>
<li>C2</li>
</ul>
</li>
</ul>
I cannot seem to understand why in the world my slide toggle is not working. could someone tell me what I'm missing? and then please explain to me what I was doing wrong? I have not done web dev in over 2 years, but this all looks solid to me, not sure what I'm missing.
$(document).ready(
function listItemsSmooth(){
$('.main-ul').children('.li').on('click', function() {
$(this).children('ul').slideToggle('slow');
});
$("#newFunction").click(listItemsSmooth);
});
.main-li-items{
display: inline-block;
text-align: center;
padding-left: 35px;
}
/*.main-li-items:hover .sub-li-items{
display:block;
}*/
.sub-li-items{
list-style-type: none;
text-align: left;
margin-left: -40.5px;
display: none
}
ul{
text-align: center;
position: absolute;
}
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"
type="text/javascript"></script>
<nav>
<nav class = "home-main-nav-menu">
<ul class = "main-ul" id ="newFunction">
<li class = "main-li-items">Home</li>
<li class = "main-li-items">About Me
<ul>
<li class = "sub-li-items">Education</li>
<li class = "sub-li-items">Lessons</li>
</ul>
</li>
<li class = "main-li-items">Blog</li>
<li class = "main-li-items">Contact
<ul>
<li class = "sub-li-items">Email</li>
<li class = "sub-li-items">Phone</li>
</ul>
</li>
<li class = "main-li-items">Portfolio
<ul>
<li class = "sub-li-items">Recent</li>
<li class = "sub-li-items">All</li>
</ul>
</li>
<li class = "main-li-items">Collaborate
<ul>
<li class = "sub-li-items"><a href = "#/">Now</li>
<li class = "sub-li-items"><a href = "#/">Later</li>
</ul>
</li>
</ul>
</nav>
</nav>
There are a couple of things contributing to this! The first is that your script is looking for a child element of class .li when it should be looking for the element li
Additionally, the CSS is hiding the <li> elements, not the <ul> which is the element being side-toggled.
$(document).ready(function(){
$('.main-ul').children('li').on('click', function() {
$(this).children('ul').slideToggle('slow');
});
});
.main-li-items{
display: inline-block;
text-align: center;
padding-left: 35px;
}
.main-li-items > ul {
display: none;
}
/*.main-li-items:hover .sub-li-items{
display:block;
}*/
.sub-li-items{
list-style-type: none;
text-align: left;
margin-left: -40.5px;
}
ul{
text-align: center;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<nav>
<nav class = "home-main-nav-menu">
<ul class = "main-ul" id = "newFunction">
<li class = "main-li-items">Home</li>
<li class = "main-li-items">About Me
<ul>
<li class = "sub-li-items">Education</li>
<li class = "sub-li-items">Lessons</li>
</ul>
</li>
<li class = "main-li-items">Blog</li>
<li class = "main-li-items">Contact
<ul>
<li class = "sub-li-items">Email</li>
<li class = "sub-li-items">Phone</li>
</ul>
</li>
<li class = "main-li-items">Portfolio
<ul>
<li class = "sub-li-items">Recent</li>
<li class = "sub-li-items">All</li>
</ul>
</li>
<li class = "main-li-items">Collaborate
<ul>
<li class = "sub-li-items">Now</li>
<li class = "sub-li-items">Later</li>
</ul>
</li>
</ul>
</nav>
</nav>
You need to correct so many things so just compare your code and my code :
Fiddle
$(document).ready(function(){
function listItemsSmooth(){
$(this).find('ul').slideToggle('slow');
}
$(".main-li-items").click(listItemsSmooth);
});
.main-li-items{
display: block;
text-align: center;
float: left;
padding-left: 21px;
}
.main-li-items > ul{
display: none;
}
.sub-li-items{
list-style-type: none;
text-align: left;
margin-left: -40.5px;
}
ul{
text-align: center;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<nav class = "home-main-nav-menu">
<ul class = "main-ul" id ="newFunction">
<li class = "main-li-items">Home</li>
<li class = "main-li-items">About Me
<ul>
<li class = "sub-li-items">Education</li>
<li class = "sub-li-items">Lessons</li>
</ul>
</li>
<li class = "main-li-items">Blog</li>
<li class = "main-li-items">Contact
<ul>
<li class = "sub-li-items">Email</li>
<li class = "sub-li-items">Phone</li>
</ul>
</li>
<li class = "main-li-items">Portfolio
<ul>
<li class = "sub-li-items">Recent</li>
<li class = "sub-li-items">All</li>
</ul>
</li>
<li class = "main-li-items">Collaborate
<ul>
<li class = "sub-li-items"><a href = "#"/>Now</li>
<li class = "sub-li-items"><a href = "#"/>Later</li>
</ul>
</li>
</ul>
</nav>
</nav>
I have a css menu I would like to make accessible through keyboard interaction. I want to be able to tab through each link including sub menu links.
If the dropdown focus moves on to the next parent link dropdown then the previous dropdown should hide.
Updated Fiddle
HTML
<ul>
<li class="custom-MainMenu-TopNav-li">
<div>
<span>Parent link 1</span>
<div>
<ul class="custom-MainMenu-SubNav-dropdown">
<li>Sub Link</li>
<li>Sub Link</li>
</ul>
</div>
</div>
</li>
<li class="custom-MainMenu-TopNav-li">
<div>
<span>Parent link 2</span>
<div>
<ul class="custom-MainMenu-SubNav-dropdown">
<li>Sub Link</li>
<li>Sub Link</li>
</ul>
</div>
</div>
</li>
</ul>
JavaScript
accessibleDropdown();
function accessibleDropdown(){
jQuery('.custom-MainMenu-TopNav-li a').each(function(){
jQuery(this).focus(function(){
jQuery(this).addClass('focused');
var menuParent = jQuery(this).parent().next().find('ul');
jQuery(menuParent).css('display','block');
});
jQuery(this).blur(function(){
jQuery(this).removeClass('focused');
});
});
}
I am not sure what is your desired outcome and need for this result, but hopefully this will help you out.
I had to redo your example due to naming convention and approach, but I assume this is what you wanted...
Here's a demo, just in case...
JSFiddle
HTML
<ul class="navbar">
<li class="navbar-item">
Parent Link
<ul class="navbar-sub">
<li class="navbar-sub-item">
One
</li>
<li class="navbar-sub-item">
Two
</li>
<li class="navbar-sub-item">
Three
</li>
</ul>
</li>
<li class="navbar-item">
Parent Link
<ul class="navbar-sub">
<li class="navbar-sub-item">
One
</li>
<li class="navbar-sub-item">
Two
</li>
<li class="navbar-sub-item">
Three
</li>
</ul>
</li>
<li class="navbar-item">
Parent Link
<ul class="navbar-sub">
<li class="navbar-sub-item">
One
</li>
<li class="navbar-sub-item">
Two
</li>
<li class="navbar-sub-item">
Three
</li>
</ul>
</li>
<li class="navbar-item">
Parent Link
<ul class="navbar-sub">
<li class="navbar-sub-item">
One
</li>
<li class="navbar-sub-item">
Two
</li>
<li class="navbar-sub-item">
Three
</li>
</ul>
</li>
</ul>
CSS
body {
margin: 10px;
}
.navbar,
.navbar .navbar-sub {
list-style: none;
margin: 0;
padding: 0;
}
.navbar > .navbar-item {
float: left;
}
.navbar > .navbar-item:last-child {
margin-right: 0;
}
.navbar > .navbar-item.active > .navbar-sub {
display: block;
}
.navbar > .navbar-item a {
text-decoration: none;
}
.navbar > .navbar-item > a {
background-color: #999;
padding: 10px 20px;
color: #696969;
display: block;
}
.navbar > .navbar-item > a:hover,
.navbar > .navbar-item > a:focus,
.navbar > .navbar-item.active > a {
background-color: #ccc;
}
.navbar .navbar-sub {
display: none;
}
.navbar .navbar-sub > .navbar-sub-item > a {
color: #ccc;
display: block;
padding: 5px 10px;
text-align: center;
background-color: #696969;
}
.navbar .navbar-item.active .navbar-sub-item > a:hover,
.navbar .navbar-item.active .navbar-sub-item > a:focus {
background-color: #999;
}
jQuery
$('.navbar').on('mouseenter focusin', '.navbar-item > a', function () {
$(this)
.parent('.navbar-item')
.addClass('active')
.siblings('.navbar-item')
.removeClass('active')
});
here you go, simple jquery :)
// display drop down box when mouse is over
$(".custom-MainMenu-TopNav-li a").mouseover(function(){
$(this).find(".custom-MainMenu-SubNav-dropdown").css("display", "block");
});
// hide drop down box when mouse leaves
$(".custom-MainMenu-TopNav-li a").mouseleave(function(){
$(this).find(".custom-MainMenu-SubNav-dropdown").css("display", "none");
});
This basically displays/hide each the dropdown when the mouse is over/leaves the parent div.
I don't think it would be a good idea to display the dropbown menu on focus, cause i believe you can only focus on certain elements like inputs.
Hope this helps!