Javascript add class to next element when nested child element is clicked - javascript

I have a menu structure where the Submenu that is hidden is not a child of the menu item. I have a span element inside the main top level link that will serve as an arrow to signify a submenu on mobile. When the user touches the span element I need the dropdown menu to have a class added (Javascript not using jQuery) in order to show it.
Something like this (Note that this is not how I would structure my menu, this is code already on a site that I cannot change)
<a href="#">Top Level Menu Item #1
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#">Top Level Menu Item #2
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#">Top Level Menu Item #3
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
So when span is touched or clicked, .dropdown-menu will have a class added to it.

Just go with span.parentNode.nextElementSibling.classList.toggle('visible');
const spans = document.querySelectorAll('a>span');
for (const span of spans) {
span.addEventListener('click', (e) => {
e.stopPropagation();
span.parentNode.nextElementSibling.classList.toggle('visible');
})
}
.dropdown-menu {
opacity: 0;
transition: all .2s ease-in-out;
}
.dropdown-menu.visible {
opacity: 1;
}
<a href="#">Top Level Menu Item #1
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#">Top Level Menu Item #2
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#">Top Level Menu Item #3
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
Please note that I have limited the click listener to the <span>⇩</span> , the link itself is not affected.
Let me know if you need IE11-compatible code.

You can just walk the dom, if that's the structure it will always have HTML wise with something like(providing you add a class to it, a wrapping class/id or something unique to the span):
const spans = Array.from(document.querySelectorAll('.dropdown-toggle'))
const addClassToSubmenu = el => {
el.target.parentNode.nextElementSibling.classList.toggle('classtoadd')
}
spans.forEach(span => {
span.addEventListener('click', addClassToSubmenu)
})
That'd do.
That's the snippet:
https://codepen.io/Venomzzz/pen/qJyvyN?editors=1010

You could try accomplishing this with jQuery next():
Note: you need to add a "menu" class to your tags and you'd need to expand the mouseout and hover calls to keep your sub-menus from going away when you mouse out of the main menu.
CSS:
.dropdown-menu {display: none }
HTML:
<a href="#" class="menu">Top Level Menu Item #1
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#" class="menu">Top Level Menu Item #2
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#" class="menu">Top Level Menu Item #3
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
JQuery:
$('.menu').hover(function() {
$(this).next().css("display", "block");
});
$('.menu').mouseout(function() {
$(this).next().css("display", "none");
});

Related

Toggle Class while removing class from siblings on owl carousel drag

I tried changing in a condition statement but it did not work. The question is as follows.
How to toggle the active class while removing the class from siblings on owl carousel drag?
<div id="resource-hashes">
<div class="container">
<a href="#" id="resource-link" class="active">
<span>Startup Resources</span>
</a>
<a href="#" id="business-link">
<span>Business Resources</span>
</a>
</div>
</div>
var owl = $('#resources');
owl.owlCarousel();
//custom buttons on click actions
owl.on('dragged.owl.carousel', function() {
$('#resource-hashes .container > a').removeClass('active').siblings().toggleClass('active');
});

submenu in another element hides after moving the mouse out

I've made a sub menu list that show/hide with jquery when user hover on li list, each li shows a separate element.
Now i'm facing a problem with the jQuery code that when mouseleave, it hide the element and can't detect the hover event over this element.
The thing is, I can make it hide when switching to another list menu item and getting out of the element block. but I need it to keep showing the submenu in case the mouse is over it.
here's the code:
$(".left-nav-list-view nav ul li").mouseenter(function () {
clearMenuFlyout();
if ($(this).data('has-submenu')) {
var submenu_id = $(this).children('a').data('menu-id');
$(".flyOut-nav-container").append($("[id=" + submenu_id + "]")).position({
my: "left+1 top+0",
at: "right top",
of: this
});
}
}).on("mouseleave", function () {
});
function clearMenuFlyout(){
$(".flyout-temp-container").append($(".flyOut-nav-container").children());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="side-nav-container flex-fixed">
<nav class="left-nav-view collapsed" role="navigation">
<div class="app-logo">
<div class="burger-menu">
<span class="burger-menu-icon"></span>
</div>
</div>
<div class="left-nav-list-view">
<nav>
<ul>
<li><span>Dashboard</span></li>
<li id="AccountingMenu" data-has-submenu="true"><a data-menu-id="AccountingMenuItems" href="#"><span>Accounting</span><i class="list-in fa fa-chevron-right"></i></a></li>
<li id="InventoryMenu" data-has-submenu="true"><a data-menu-id="InventoryMenuItems" href="#"><span>Inventory</span><i class="list-in fa fa-chevron-right"></i></a></li>
</ul>
</nav>
</div>
</nav>
</div>
basically clearFlyout function takes an already existent menu element and throw it to another div. .flyout-temp-container is hidden by default

Remove class with Jquery on a different item

I have a mobile menu button that has an animation, the class changes on click of the menu and click backs to normal when clicked again. A menu also pops out on click.
I want the animation end state to also click back to normal when I click one of the pop out menu anchor links.
Here is my HTML code:
<div class="o-grid__item">
<button id="menu" class="c-hamburger c-hamburger--htx">
<span>toggle menu</span>
</button>
</div>enter code here
<nav class="main-menu">
<ul>
<li>
<a href="#welcome">
<i class="fa"></i>
<span class="nav-text">Home</span>
</a>
</li>
<li>
<a href="#portfolio">
<i class="fa"></i>
<span class="nav-text">Work</span>
</a>
</li>
<li>
<a href="#about">
<i class="fa"></i>
<span class="nav-text">About</span>
</a>
</li>
<li>
<a href="#contact">
<i class="fa"></i>
<span class="nav-text">Contact</span>
</a>
</li>
</ul>
</nav>
Here is the script I'm using to toggle the menu
$(document).ready(function(){
$(".c-hamburger").click(function(){
$(".main-menu").toggleClass("expand-menu");
});
});
Here is the code for the remove/add class for animating the button.
(function() {
"use strict";
var toggles = document.querySelectorAll(".c-hamburger");
for (var i = toggles.length - 1; i >= 0; i--) {
var toggle = toggles[i];
toggleHandler(toggle);
};
function toggleHandler(toggle) {
toggle.addEventListener( "click", function(e) {
e.preventDefault();
(this.classList.contains("is-active") === true) ? this.classList.remove("is-active") : this.classList.add("is-active");
});
}
})();
I need to know how to add remove this class for the menu button, on click of one of my list items in my list? any help much appreciated.
to remove a class from an element instead of just toggling it, use the .removeClass extension for the JQuery element selector. Add this to the anchor links
If you are using jquery anyways, then use this for the class toggling logic
$(".main-menu ul li a").click( function(){
e.preventDefault();
$(this).closest("li").toggleClass("is-active").siblings().removeClass("is-active");
});

Open and scroll to accordion section

I have a single page site with content placed inside an accordion. I need to both open and scroll to the accordion item when a user clicks on my nav at the top of the page. I found a couple similar functions, this being the closest (Open JQuery accordion when link with an id of element within the accordion is clicked) but unfortunately the jsfiddle links are no longer working.
Right now I just have thecode to get the accordion working...Need to get the scroll to part in there somehow...Thanks!
Code
var accordion_head = $('.accordion > li > .toggle-bar');
accordion_head.on('click', function (event) {
var $a = $(this);
event.preventDefault();
if ($a.hasClass('active')) {
$a.removeClass('active').siblings('.content-wrapper').slideUp();
}
else {
$a.addClass('active').siblings('.content-wrapper').slideDown();
}
});
.accordion li .content-wrapper {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="accordion">
<li id="1">
<a class="toggle-bar" href="#one"><h2>Headline</h2></a>
<div class="content-wrapper">
Content Here
</div>
</li>
<li id="2">
<a class="toggle-bar" href="#two"><h2>Headline</h2></a>
<div class="content-wrapper">
Content Here
</div>
</li>
<li id="3">
<a class="toggle-bar" href="#three"><h2>Headline</h2></a>
<div class="content-wrapper">
Content Here
</div>
</li>
</ul>

javaScript changing parent menu item when child item is active

I'm pretty new to the javaScript and it would be very helpful for me if somebody could be so glad to give me some directions how to perform that. I'm creating website in Joomla 3 and I need to stylize the menu in a way that when a child menu item is active the parent item should change the background colour. I included the .js link into the head of the index.php file of my template. But I'm struggling second day with the desired script.
Here is my HTML:
<ul class="gf-menu l1">
<li class="item128 parent">
<a class="item" href"services">Services<span class="border-fixer"></span>::after</a>
<div class="dropdown columns-1">
<div class="column col1">
<ul class="l2">
<li class ="item1"><a class="item" href="submenu-01">Submenu1</a></li>
<li class ="item2"><a class="item" href="submenu-02">Submenu2</a></li>
<li class ="item3"><a class="item" href="submenu-03">Submenu3</a></li>
</ul>
</div>
</div>
</li>
</ul>
And that's it my CSS for it:
.gf-menu .dropdown{
border: 1px solid transparent;
border-radius:0;
background-color:#a9a9a9;
padding:10% 0;
width:100%;
text-shadow:none;
font-size:85%;
}
.gf-menu.l1 li.item1.active.last {background-color:#abcf39;}
.gf-menu.l1 li.item2.active.last {background-color:#f39512;}
.gf-menu.l1 li.item3.active.last {background-color:#f16e68;}
If you click on the <li> element and want to affect the parent you can use the .parent() method to target the parent element. The question is which one do you want to target. If it's the div which contains the <ul> you will have to access the parent of a parent. For example if the <li> has a class item as you stated in your question, you can do
$('.item').on('click', function(){
var clickedLiElement = $(this);
var parentHoldingUl = clickedLiElement.parent().parent();
//now you can do whatever you want with both of them, for example
clickedLiElement.addClass('active');
parentHoldingUl.css('background-color', 'green');
});
Update based on comments:
A slightly shorter version, which does what you specified in the comments
$('.item').on('click', function(){
$(this).css('background-color', '#5512F3');
$(this).parent().parent().css('background-color', '#5512F3');
$(this).siblings().css('background-color', '#AB99D5');
});
This should turn the clicked LI element and it's parent DIV dark blue and the clicked elemnent's siblings light blue.

Categories