jquery menu with slide from left for sub menus - javascript

I wanted to slide sub menus from left or right if i click on li.menu-items for each item of a menu which have sub menus. here is my html markup
<ul class="menu">
<ul>
<li class="menu-item">
<a href="#">item 1
</a>
<ul class="sub-menu">
<li class="menu-item">
item 2
</li>
<li class="menu-item">
<ul class="sub-menu">
<li><a href="">item 1</li></li>
<li><a href="">item 1</li></li>
</ul>
</li>
</ul>
</li>
<li class="menu-item">
item 4
<ul class="sub-menu">
<li class="menu-item">
item5
</li>
<li class="menu-item">
item 6
</li>
</ul>
</li>
<li class="menu-item">item 7</li>
<li class="menu-item">item 8</li>
</ul>
</ul>
if I click on menu item which have sub-menu then the sub menu will open from slide left or right and other menu items should be hide and a back button should be there at top left to back on main menu
here is my js
$('.menu-item').click(function(e){
if ($('.sub-menu', this).length >=1) {
e.preventDefault();
}
$(this).siblings().find('> .sub-menu').hide();
$(this).find('> .sub-menu').slideLeft();
e.stopPropagation();
});
please help me for this

I don't think is there any function in jQuery like slideLeft as far as I know. although you can do it with jQuery UI with a little trick like this.
$(this).show("slide", { direction: "left" }, 1000);
but I will prefer a custom CSS example based on jQuery classes.
check below code example. if you need anything else. please let me know.
and yes you also did a small mistake: you are having a UL direct child of your Menu UL, Ul can only have LI as a direct child, Correct it and pls close all the tags properly.
$('.menu-item').click(function(e) {
if ($('.sub-menu', this).length >= 1) {
e.preventDefault();
}
debugger;
$(this).siblings().find('> .sub-menu').removeClass('open');
$(this).find('> .sub-menu').addClass("open");
e.stopPropagation();
});
$('.back').click(function(e){
$(this).closest('.sub-menu').removeClass('open');
e.stopPropagation();
})
.menu {
background: #cccccc;
position: relative;
}
* {padding :0; margin: 0; box-sizing: border-box;}
.sub-menu {
display: block;
position: absolute;
height: auto;
width: 100%;
left: -100%;
transition: all 0.5s;
top: 0%;
}
.sub-menu.open {
left: 0;
background: #666;
}
.back {cursor: pointer; margin-bottom: 20px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu">
<li class="menu-item">
item 1
<ul class="sub-menu">
<li class="back">back</li>
<li class="menu-item">
item 2
</li>
<li class="menu-item">
<ul class="sub-menu">
<li class="back">back</li>
<li>item 1</li>
<li>item 1</li>
</ul>
</li>
</ul>
</li>
<li class="menu-item">
item 4
<ul class="sub-menu">
<li class="back">back</li>
<li class="menu-item">
item5
</li>
<li class="menu-item">
item 6
</li>
</ul>
</li>
<li class="menu-item">item 7</li>
<li class="menu-item">item 8</li>
</ul>

My code is not jQuery but I hope it works for you.
var x = document.getElementsByClassName('menu');
var y = x[0].getElementsByTagName('a');
for (let i = 0; i < y.length; i++) {
y[i].addEventListener("click", function () {
var z = this.nextElementSibling;
if(z){
var s = z.getAttribute('style');
if(s === 'display:none;') {
z.setAttribute('style', 'display:block;')
} else {
z.setAttribute('style', 'display:none;')
}
}
});
}
<ul class="menu">
<ul>
<li class="menu-item">
item 1
<ul class="sub-menu">
<li class="menu-item">
item 2
</li>
<li class="menu-item">
item 3
<ul class="sub-menu">
<li class="menu-item">
item 4
</li>
<li class="menu-item">
item 5
</li>
</ul>
</li>
<li class="menu-item">
item 6
</li>
</ul>
</li>
</ul>
</ul>

Related

How to check the continue classes in set?

I have 10 items in a list with this kind of structure where any item can have active class depending on some situations and this active class will add on item when user click on it. I want to get the number of set of 3 continue active classes. in the given example the 3 continue active classes are 2 times on items 4,5,6 and 8,9,10.
So the output should be 2 only.
How to achieve this.
I know I can get the total number of Active classes just by getting its length, but how to get if its how many times in continuity?
$(document).ready(function(){
let totalActivce = $('.active').length;
console.log(totalActivce);
});
.active {color: red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="active">item1 </li>
<li>item2 </li>
<li>item3 </li>
<li class="active">item4 </li>
<li class="active">item5 </li>
<li class="active">item6 </li>
<li>item7 </li>
<li class="active">item8 </li>
<li class="active">item9 </li>
<li class="active">item10 </li>
</ul>
If you want to count the elements between your first element with the class active and the next you can use $('.active:first').nextUntil(".active")
Demo
$(document).ready(function() {
let totalActivce = $('.active:first').nextUntil(".active").length;
console.log(totalActivce);
});
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="active">item1 </li>
<li>item2 </li>
<li>item3 </li>
<li class="active">item4 </li>
<li class="active">item5 </li>
<li class="active">item6 </li>
<li>item7 </li>
<li class="active">item8 </li>
<li class="active">item9 </li>
<li class="active">item10 </li>
</ul>
Demo 2
$(document).ready(function() {
var f = 0;
$("ul li").each(function() {
if ($(this).is(".active") && $(this).nextUntil(':not(.active)').addBack().length == 3) {
f++;
}
});
console.log(f);
});
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="active">item1 </li>
<li>item2 </li>
<li>item3 </li>
<li class="active">item4 </li>
<li class="active">item5 </li>
<li class="active">item6 </li>
<li>item7 </li>
<li class="active">item8 </li>
<li class="active">item9 </li>
<li class="active">item10 </li>
</ul>
Demo 3
$(document).ready(function() {
var f = 0;
var s = 1;
$("ul li").each(function(i) {
if (s <= i) {
if ($(this).is(".active") && $(this).nextUntil(':not(.active)').addBack().length >= 3) {
s = s + 3;
f++;
}
}
});
console.log(f);
});
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li>item1 </li>
<li class="active">item2 </li>
<li class="active">item3 </li>
<li class="active">item4 </li>
<li class="active">item5 </li>
<li class="active">item6 </li>
<li class="active">item7 </li>
<li class="active">item8 </li>
<li class="active">item9 </li>
<li class="active">item10 </li>
</ul>
You can loop your elements and check if previous elements where active:
$(document).ready(function() {
let totalActivce = $('.active').length;
let sets = 0;
let isPreviousActive = 0;
console.log(totalActivce);
$('ul li').each(function() {
let isActive = $(this).is('.active');
if (isActive) {
isPreviousActive++;
if (isPreviousActive == 2) {
sets++;
}
}
if (!isActive) {
isPreviousActive = 0;
}
});
console.log(sets);
});
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="active">item1 </li>
<li>item2 </li>
<li>item3 </li>
<li class="active">item4 </li>
<li class="active">item5 </li>
<li class="active">item6 </li>
<li>item7 </li>
<li class="active">item8 </li>
<li class="active">item9 </li>
<li class="active">item10 </li>
</ul>

How to create dynamic menu with list items?

I am trying to create a menu using list item's and unordered list's that are nested within each other to display sub menus. When each list item is clicked, it will display the child unordered list by adding the "show" class. I can't seem to figure out how to remove the "show" class once one of the "topLevel" list item components is clicked (those are the three main menu options).
Here's the jsFiddle: https://jsfiddle.net/eu1rc4ma/2/
Thanks in advance!
Tried using spans to remove the class from all child components.
<div class="container">
<div class="menu">
<ul class="show">
<li>
<span class="topLevel">Services</span>
<ul>
<li>
1
<ul>
<li>1.1</li>
<li>1.2</li>
<li>1.3</li>
</ul>
</li>
<li>
2
<ul>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
</ul>
</li>
<li>
3
<ul>
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
</ul>
</li>
</ul>
</li>
<li>
<span class="topLevel">Technology</span>
<ul>
<li>
1
<ul>
<li>1.1</li>
<li>1.2</li>
<li>1.3</li>
</ul>
</li>
<li>
2
<ul>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
</ul>
</li>
<li>
3
<ul>
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
</ul>
</li>
</ul>
</li>
<li>
<span class="topLevel">About</span>
<ul>
<li>
1
<ul>
<li>1.1</li>
<li>1.2</li>
<li>1.3</li>
</ul>
</li>
<li>
2
<ul>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
</ul>
</li>
<li>
3
<ul>
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
ul {
display: none;
}
.show {
display: flex;
flex-direction: column;
}
let targets = document.querySelectorAll("li");
targets.forEach(function(target) {
target.addEventListener("click", function() {
let subMenu = target.querySelector("ul");
subMenu.classList.add("show");
});
});
Try this by checking if ul has .show
let targets = document.querySelectorAll("li");
let main, sub;
targets.forEach(function(target) {
if (target.parentElement.parentElement.tagName == "DIV") { // for mains
target.addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
let subMenu = target.querySelector("ul");
toggleClass(subMenu);
if (main && main != subMenu) {
main.classList.remove("show")
}
main = subMenu;
});
} else if (target.parentElement.parentElement.parentElement.parentElement.tagName == "DIV") {
target.addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
let subMenu = target.querySelector("ul");
toggleClass(subMenu);
if (sub && sub != subMenu) {
sub.classList.remove("show")
}
sub = subMenu;
});
} else {
target.addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
});
}
});
function toggleClass(subMenu) {
if (subMenu.className.includes('show')) {
subMenu.classList.remove("show")
} else {
subMenu.classList.add("show");
}
}
ul {
display: none;
}
.show {
display: flex;
flex-direction: column;
}
<div class="container">
<div class="menu">
<ul class="show">
<li>
<span class="topLevel">Services</span>
<ul>
<li>
1
<ul>
<li>1.1</li>
<li>1.2</li>
<li>1.3</li>
</ul>
</li>
<li>
2
<ul>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
</ul>
</li>
<li>
3
<ul>
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
</ul>
</li>
</ul>
</li>
<li>
<span class="topLevel">Technology</span>
<ul>
<li>
1
<ul>
<li>1.1</li>
<li>1.2</li>
<li>1.3</li>
</ul>
</li>
<li>
2
<ul>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
</ul>
</li>
<li>
3
<ul>
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
</ul>
</li>
</ul>
</li>
<li>
<span class="topLevel">About</span>
<ul>
<li>
1
<ul>
<li>1.1</li>
<li>1.2</li>
<li>1.3</li>
</ul>
</li>
<li>
2
<ul>
<li>2.1</li>
<li>2.2</li>
<li>2.3</li>
</ul>
</li>
<li>
3
<ul>
<li>3.1</li>
<li>3.2</li>
<li>3.3</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
Try this code in order to toggle your list:
let
let targets = document.querySelectorAll("li");
targets.forEach(function(target) {
target.addEventListener("click", function() {
let subMenu = target.querySelector("ul");
let isOpen = subMenu.classList.contains('show');
if (!isOpen) {
subMenu.classList.add("show");
} else {
subMenu.classList.remove("show");
}
});
});
working jsfiddle
https://jsfiddle.net/vfxtcbpd/2/

Find ul with a specific li item in a collection of ul and than add class to it

I have a collection of unordered lists. I would like to iterate through this list and than find an specific li item and than add a class to the ul containing that li.
I hope I was clear enough for you guys. Let me show you my code for better understanding.
This is a fiddle I created to help you understand my problem.
https://jsfiddle.net/wdwn9swu/
This is what I tried to target the ul I need but it didn't work.
if ($('ul.sub-tab').find('ul.sub-tab > li.super-active')) {
$('ul.sub-tab').find('li.super-active').addClass('super-active');
}
I would like that on of the lists that corresponds with the id, to always be open.
Any idea guys ?? Thanks!!
I think the easiest and simplest way is:
$("li.super-active").parent().addClass("super-active");
According the fact you are using valid html <li> element parent must be <ul> element in that case (can also be <ol>).
$('.main-tab>li a').click(function() {
$(this).siblings('.sub-tab').slideToggle(200);
$(this).parent().siblings('li').children('.sub-tab').slideUp(200);
});
$('.main-tab li').each(function() {
id = '10';
$links = $(".main-tab li[data-id =" + id + "]");
$links.addClass("super-active");
//console.log("1234");
});
$("li.super-active").parent().addClass("super-active");
console.log($(".super-active"));
.main-tab ul {
padding-left: 10px;
}
.sub-tab {
display: none;
}
.super-active img {
display: block !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="center">
<ul class="main-tab">
<li data-id="5">
Main 1
<ul class="sub-tab">
<li data-id="7">
Main 1 Sub 1
<ul class="sub-tab">
<li data-id="10">Sub 2</li>
<li data-id="11">Sub 2</li>
</ul>
</li>
<li>
Main 1 Sub 2
<ul class="sub-tab">
<li data-id="12">Sub 2</li>
<li data-id="13">Sub 2</li>
</ul>
</li>
</ul>
</li>
<li data-id="8">
Main 2
<ul class="sub-tab">
<li data-id="9">
Main 2 Sub 1
<ul class="sub-tab">
<li data-id="14">Sub 2</li>
<li data-id="15">Sub 2</li>
</ul>
</li>
</ul>
</li>
<li data-id="3">
Main 3
<ul class="sub-tab">
<li data-id="25">
Main 3 Sub 1
<ul class="sub-tab">
<li data-id="17">Sub 2</li>
<li data-id="18">Sub 2</li>
</ul>
</li>
</ul>
</li>
</ul>
Use jQuery's :has selector:
Selects elements which contain at least one element that matches the
specified selector.
Find ul.sub-tab that has a list item with .super-active class, and add the class .super-active to the ul as well:
$('ul.sub-tab:has(li.super-active)').addClass('super-active');
Example:
$('ul.sub-tab:has(li.super-active)').addClass('super-active');
.sub-tab.super-active {
background: gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="center">
<ul class="main-tab">
<li data-id="5">
Main 1
<ul class="sub-tab"> <!-- this will be removed -->
<li data-id="7" class="super-active">
Main 1 Sub 1
<ul class="sub-tab">
<li data-id="10">Sub 2</li>
<li data-id="11">Sub 2</li>
</ul>
</li>
<li>
Main 1 Sub 2
<ul class="sub-tab">
<li data-id="12">Sub 2</li>
<li data-id="13">Sub 2</li>
</ul>
</li>
</ul>
</li>
<li data-id="8">
Main 2
<ul class="sub-tab">
<li data-id="9">
Main 2 Sub 1
<ul class="sub-tab">
<li data-id="14">Sub 2</li>
<li data-id="15">Sub 2</li>
</ul>
</li>
</ul>
</li>
<li data-id="3">
Main 3
<ul class="sub-tab">
<li data-id="25">
Main 3 Sub 1
<ul class="sub-tab">
<li data-id="17">Sub 2</li>
<li data-id="18">Sub 2</li>
</ul>
</li>
</ul>
</li>
</ul>

jQuery selector for li in ul li

I create a menu & want to when click on li children just child set .active class no li parent
(Use in enfold WordPress theme)
$('#mobile-advanced li.menu-item-has-children').on('click', function () {
$(this).toggleClass('active');
});
// just for test
$('a').on('click', function (e) {
e.preventDefault() ;
});
li.active{
background-color: #FFB94B;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="mobile-advanced">
<li class="menu-item menu-item-has-children">
T 1
<ul>
<li class="menu-item menu-item-has-children">
T11
<ul>
<li class="menu-item">T111</li>
<li class="menu-item">T112</li>
</ul>
</li>
<li class="menu-item">T12</li>
<li class="menu-item">T13</li>
</ul>
</li>
<li class="menu-item">
T 2
</li>
</ul>
for example, when I click li children li parent set active class
you can detect event click with a tags :
$('#mobile-advanced li.menu-item-has-children a').on('click', function () {
$(this).parent().toggleClass('active');
});
// just for test
$('a').on('click', function (e) {
e.preventDefault() ;
});
li.active{
background-color: #FFB94B;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="mobile-advanced">
<li class="menu-item menu-item-has-children">
T 1
<ul>
<li class="menu-item menu-item-has-children">
T11
<ul>
<li class="menu-item">T111</li>
<li class="menu-item">T112</li>
</ul>
</li>
<li class="menu-item">T12</li>
<li class="menu-item">T13</li>
</ul>
</li>
<li class="menu-item">
T 2
</li>
</ul>
You just need add another class into the element you want to change. In my case, i define anther class called "active-this" and apply the jquery function to this class. Follow the example:
$('.active-this').on('click', function () {
$(this).toggleClass('active');
});
// just for test
$('a').on('click', function (e) {
e.preventDefault() ;
});
li.active{
background-color: #FFB94B;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="mobile-advanced">
<li class="menu-item menu-item-has-children">
T 1
<ul>
<li class="menu-item menu-item-has-children">
T11
<ul>
<li class="menu-item active-this">T111</li>
<li class="menu-item active-this">T112</li>
</ul>
</li>
<li class="menu-item active-this">T12</li>
<li class="menu-item active-this">T13</li>
</ul>
</li>
<li class="menu-item">
T 2
</li>
</ul>
You can use the below selector to be able to click on li menu items excluding parent li elements.
$('#mobile-advanced li.menu-item').not(".menu-item-has-children")
$('#mobile-advanced li.menu-item').not(".menu-item-has-children").on('click', function (e) {
e.preventDefault();
$(this).toggleClass('active');
});
$(".menu-item-has-children").on('click', function(e){
e.preventDefault();
})
li.active {
background-color: #FFB94B;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<ul id="mobile-advanced">
<li class="menu-item menu-item-has-children">
T 1
<ul>
<li class="menu-item menu-item-has-children">
T11
<ul>
<li class="menu-item">
T111
</li>
<li class="menu-item">
T112
</li>
</ul>
</li>
<li class="menu-item">
T12
</li>
<li class="menu-item">
T13
</li>
</ul>
</li>
<li class="menu-item">
T 2
</li>
</ul>

Zurb Foundation dropdown position to very first parent

In Foundation 6 by default, dropdown menus appear on the same level as the parent like so:
Is there a way to make it so that the menu appears on the same level as the first menu? This is the desired outcome:
I have looked through the documentation and cannot seem to find a way to do it. Thanks in advance!
This is a snippet of the default code from Foundation site
<ul class="dropdown menu" data-dropdown-menu>
<li>
<a>Item 1</a>
<ul class="menu">
<li>Item 1A Loooong
</li>
<li>
<a href='#'> Item 1 sub</a>
<ul class='menu'>
<li><a href='#'>Item 1 subA</a>
</li>
<li><a href='#'>Item 1 subB</a>
</li>
<li>
<a href='#'> Item 1 sub</a>
<ul class='menu'>
<li><a href='#'>Item 1 subA</a>
</li>
<li><a href='#'>Item 1 subB</a>
</li>
</ul>
</li>
<li>
<a href='#'> Item 1 sub</a>
<ul class='menu'>
<li><a href='#'>Item 1 subA</a>
</li>
</ul>
</li>
</ul>
</li>
<li>Item 1B
</li>
</ul>
</li>
<li>
Item 2
<ul class="menu">
<li>Item 2A
</li>
<li>Item 2B
</li>
</ul>
</li>
<li>Item 3
</li>
<li><a href='#'>Item 4</a>
</li>
</ul>
Here is a fiddle of the default: http://jsfiddle.net/65017wc2/
Here is a possible fix to do this :
.dropdown.menu {
top: 0!important;
}
.dropdown.menu {
position: relative;
}
.dropdown.menu li {
position: static !important;
}
.dropdown.menu ul {
margin-top: -1px;
}
I overwrite the relative position of li elements to the native static position and made the main ul relative, so all the dropdown menus are relative to the main ul menu.
See this fiddle

Categories

Resources