I have:
heading
submenu
heading
submenu
submenu
s are hidden by default. When clicking on a heading, I want to display its submenu and hide the other submenus if they are displaying.
I have inherited Beaver Builder/WordPress so the code is bloated unfortunately.
I'm looking to toggle #ftr-menu-company.footer-text-links
when clicking #ftr-hdr-company
and hide #ftr-menu-product.footer-text-links
if it is open.
On clicking either #ftr-hdr-company
or #ftr-hdr-product
I'd like to toggleClass("hideBlock")
on .footer-text-links
children of self
s parent, i.e. the .footer-text-links
in the same .fl-col
block & then addClass("hide-block")
on all other .footer-text-links
.
This is not producing any effect.
I am not sure if I can actually perform $(self).parent().children(".footer-text-links").toggleClass("hide-block")
.
Help appreciated.
$(document).ready(function(){
$("#ftr-hdr-company").click(function() {
showSubMenu(self);
});
$("#ftr-hdr-product").click(function() {
showSubMenu(self);
});
})
function showSubMenu(self) {
$(".footer-text-links")
.not($(self).parent().children(".footer-text-links").toggleClass("hide-block"))
.addClass("hide-block");
}
#ftr-menu-company.hide-block, #ftr-menu-product.hide-block {display: none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
<div >
<div id="ftr-hdr-company" >
<div >
<h4 ><span >Company</span></h4>
</div>
</div>
<div id="ftr-menu-company"
>
<div >
<div >
<div ></div>
<nav>
<ul>
<li><a href="#">About Us</a></li>
<li><a href="#">Careers</a></li>
<li><a href="#">Enterprise</a></li>
<li><a href="#">Customers</a></li>
<li><a href="#">Partner Program</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div >
<div >
<div id="ftr-hdr-product" >
<div >
<h4 ><span >Product</span></h4>
</div>
</div>
<div id="ftr-menu-product" >
<div >
<div >
<div ></div>
<nav>
<ul>
<li><a href="#">Features</a></li>
<li><a href="#">How It Works</a></li>
<li><a href="#">Templates</a></li>
<li><a href="#">Industries</a></li>
<li><a href="#">Use Cases</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>
CodePudding user response:
- Don't use IDs if you're already using classes
- Use jQuery's
.closest()
to refer to a closest parent (or self) before than traversing back using.find()
in search for a child - Use
.toggleClass()
to toggle the class - Use just
.hide-block { display: none; }
in CSS - Use just
$(".fl-module-heading").on("click", showSubMenu);
and then usethis
in your function as a reference to your clicked Event currentTarget Element (the button)
function showSubMenu() {
const $menuAll = $(".fl-col-content").find(".fl-module-menu");
const $menu = $(this).closest(".fl-col-content").find(".fl-module-menu");
$menuAll.not($menu).addClass("hide-block"); // Hide all but target menu
$menu.toggleClass("hide-block"); // Toggle target menu
}
jQuery($ => { // DOM is Ready and $ alias in scope
$(".fl-module-heading").on("click", showSubMenu);
});
.hide-block { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
<div >
<div id="ftr-hdr-company" >
<div >
<h4 ><span >Company</span></h4>
</div>
</div>
<div id="ftr-menu-company" >
<div >
<div >
<div ></div>
<nav>
<ul>
<li><a href="#">About Us</a></li>
<li><a href="#">Careers</a></li>
<li><a href="#">Enterprise</a></li>
<li><a href="#">Customers</a></li>
<li><a href="#">Partner Program</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div >
<div >
<div id="ftr-hdr-product" >
<div >
<h4 ><span >Product</span></h4>
</div>
</div>
<div id="ftr-menu-product" >
<div >
<div >
<div ></div>
<nav>
<ul>
<li><a href="#">Features</a></li>
<li><a href="#">How It Works</a></li>
<li><a href="#">Templates</a></li>
<li><a href="#">Industries</a></li>
<li><a href="#">Use Cases</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
CodePudding user response:
The easiest way to do that is adding a new attribute to the div
that you want to toggle.
I added new attribute which name is data-target
to your fl-module divs
. So, you can easily define your real target about that div
in the Javascript part.
The another problem in your code was self
. To define the element that has action, you need to use this
. I changed that part and also I made some improvements and simplifications in your Jquery code.
$(document).ready(function(){
$("div[id^='ftr-hdr-']").on('click',function() {
showSubMenu($(this));
});
})
function showSubMenu(evt) {
$("div.fl-module:not([class*='hide-block'])").addClass("hide-block"); //add hide-block to all fl-modules if it has not already one.
$(evt.attr('data-target')).toggleClass("hide-block");
}
#ftr-menu-company.hide-block, #ftr-menu-product.hide-block {display: none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
<div >
<div id="ftr-hdr-company" data-target="#ftr-menu-company" >
<div >
<h4 ><span >Company</span></h4>
</div>
</div>
<div id="ftr-menu-company"
>
<div >
<div >
<div ></div>
<nav>
<ul>
<li><a href="#">About Us</a></li>
<li><a href="#">Careers</a></li>
<li><a href="#">Enterprise</a></li>
<li><a href="#">Customers</a></li>
<li><a href="#">Partner Program</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div >
<div >
<div id="ftr-hdr-product" data-target="#ftr-menu-product" >
<div >
<h4 ><span >Product</span></h4>
</div>
</div>
<div id="ftr-menu-product" >
<div >
<div >
<div ></div>
<nav>
<ul>
<li><a href="#">Features</a></li>
<li><a href="#">How It Works</a></li>
<li><a href="#">Templates</a></li>
<li><a href="#">Industries</a></li>
<li><a href="#">Use Cases</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>