Display links in side menu when main nav links are hovered - javascript

I want to show links in the side menu, depending on what link is hovered in the top nav, and display them until another link is hovered. Here's what I have:
HTML:
<ul class="nav navbar-nav">
<li class="nav"><a class="toggle" href="#">LINK 1</a></li>
<li class="nav"><a class="toggle" href="#">LINK 2</a></li>
<li class="nav"><a class="toggle" href="#">LINK 3</a></li>
<li class="nav"><a class="toggle" href="#">LINK 4</a></li>
<li class="nav"><a class="toggle" href="#">LINK 5</a></li>
<li class="nav"><a class="toggle" href="#">LINK 6</a></li>
</ul>
<div class="sideMenu">
<div id="sideMenuLinks">
<ul id="menuContent" class="menuContent collapse out">
<li>SM LINK 1</li>
<li>SM LINK 2</li>
<li>SM LINK 3</li>
<li>SM LINK 4</li>
<li>SM LINK 5</li>
<li>SM LINK 6</li>
</ul>
</div>
</div>
jQuery:
$(document).ready(function() {
$('.toggle').hover(function () {
$('#sideMenuLinks').show('slow');
});
});
This works to just display on hover but obviously only for sideMenuLinks, I have more links in different ID's, so if I hovered on "LINK 2" those links would be replaced and so on. Make sense?
Thanks!

I would add a data-* attribute to the main navigation links like so:
<ul class="nav navbar-nav">
<li class="nav"><a class="toggle" data-menu="first" href="#">LINK 1</a></li>
<li class="nav"><a class="toggle" data-menu="second" href="#">LINK 2</a></li>
<li class="nav"><a class="toggle" data-menu="third" href="#">LINK 3</a></li>
</ul>
<div class="sideMenu">
<div id="sideMenuLinks">
<ul id="first" class="menuContent collapse out">
<li>SM LINK 1</li>
<li>SM LINK 2</li>
</ul>
<ul id="second" class="menuContent collapse out">
<li>SM LINK 1</li>
<li>SM LINK 2</li>
</ul>
<ul id="third" class="menuContent collapse out">
<li>SM LINK 1</li>
<li>SM LINK 2</li>
</ul>
</div>
</div>
Then you could get the data-menu value when hovering:
$(".toggle").hover(function() {
$(".menuContent").each(function() {
$(this).hide();
});
var menu = $(this).attr("data-menu");
$('#' + menu).show('slow');
});
Haven't tested this, but this could eventualy make the menus a little bit more dynamic.

If i comprehend correctly, you have several ID's, that you only want te have shown, when a corresponding link is hovered somewhere else on the page.
So, what you could make is a bit more of what you got going. Imagine you got this HTML:
<ul class="nav navbar-nav">
<li class="nav"><a class="toggle1" href="#">LINK 1</a></li>
<li class="nav"><a class="toggle2" href="#">LINK 2</a></li>
<li class="nav"><a class="toggle3" href="#">LINK 3</a></li>
</ul>
<div class="sideMenu">
<div id="sideMenuLinks1">
<ul id="menuContent" class="menuContent collapse out">
<li>SM LINK 1</li>
<li>SM LINK 2</li>
<li>SM LINK 3</li>
<li>SM LINK 4</li>
<li>SM LINK 5</li>
<li>SM LINK 6</li>
</ul>
</div>
<div id="sideMenuLinks2">
<ul id="menuContent" class="menuContent collapse out">
<li>SM LINK 1</li>
<li>SM LINK 2</li>
<li>SM LINK 3</li>
<li>SM LINK 4</li>
<li>SM LINK 5</li>
<li>SM LINK 6</li>
</ul>
</div>
<div id="sideMenuLinks3">
<ul id="menuContent" class="menuContent collapse out">
<li>SM LINK 1</li>
<li>SM LINK 2</li>
<li>SM LINK 3</li>
<li>SM LINK 4</li>
<li>SM LINK 5</li>
<li>SM LINK 6</li>
</ul>
</div>
</div>
Now you can use a simple for loop and the jQuery you already got, to get it going.
jQuery:
$(document).ready(function() {
for(i=0,i<3,i++){
classname = '.toggle'+i;
id = '#sideMenuLinks'+i;
$(classname).hover(function () {
$(id).show('slow');
});
}
});
I have not tested this, but its a simple, comprehensive solution. Hope this helped you!
.

Related

Make parent link unclickable in submenu toggle

I am trying to make a sub-menu toggle on mobile but it keeps on redirecting to the parent menu link and adding event.preventDefault(); making entire sub-menu links unclickable. Any idea how to make only first .has-childern a link unclickable?
Markup
<div class="menu-container">
<ul class="nav-menu">
<li class="menu item"> Home </li>
<li class="menu-item has-childern"> About
<ul class="submenu">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</li>
<li class="menu-item has-childern"> Services
<ul class="submenu">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</li>
<li class="menu item"> Contact </li>
</ul>
</div>
jQuery
jQuery(document).ready(function(){
jQuery('.menu-container .submenu').hide();
jQuery('.menu-container .has-childern a').click(function() {
event.preventDefault();
jQuery(this).parent().children('.submenu').toggle();
});
});
JsFiddle https://jsfiddle.net/p5fLsvcq/
You code affect all nested children instead just direct child
use '>' for select just a direct first level child in selector:
jQuery('.menu-container .has-childern > a').click(/*...*/)

JQuery insertBefore() duplicating insert

I have the following markup:
<div class="mobile-menu">
<ul>
<li class="product">
Link
<ul>
<li>Link</li>
<li>Link</li>
<li class="item-has-children">
Link has submenu
<ul>
<li>submenu link</li>
<li>submenu link</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
What I'm trying to do is move the submenu (li.item-has-children) as the first li item under .product. So my markup looks like this:
<div class="mobile-menu">
<ul>
<li class="product">
Link
<ul>
<li class="item-has-children">
Link has submenu
<ul>
<li>submenu link</li>
<li>submenu link</li>
</ul>
</li>
<li>Link</li>
<li>Link</li>
</ul>
</li>
</ul>
</div>
I have managed to move the li item to the top, but it's duplicating. As in my rendered markup with my JQuery below looks something like this:
<div class="mobile-menu">
<ul>
<li class="product">
Link
<ul>
<li>
Link has submenu
<ul>
<li>submenu link</li>
<li>submenu link</li>
<li>
<ul>
<li>Link has submenu</li>
<li>
<ul>
<li>submenu link</li>
<li>submenu link</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
The submenu is basically duplicating within each other and aI think it's to do with the way I'm using insertBefore(). I think it's targeting nested li elements too:
$('.mobile-menu ul li.product ul li.item-has-children').insertBefore($('.mobile-menu ul > li.product ul:first-of-type li:first-child'));
I simply want to move li.item-has-children as the first item in the li.product ul

DOM traversal from a span element inside an anchor to list

I can't figure how to travers the DOM, starting from <span class = "open-menu-link">, I want to reach <ul class="sub-menu"> .
The script
<script> $('.open-menu-link').click(function(e){
alert(e.currentTarget);
});
</script>
return a Object HTMLSpanElement, but if I code e.currentTarget.parentNode; it returns http://localhost/mysite/home.php. Doing e.currentTarget.children; I get Object HTMLCollection, but if I try e.currentTarget.children[1] I get undefined... so how can I reach <ul class="sub-menu">?
The snippet is the follow:
<ul class="menu">
<li>Work</li>
<li class="menu-item-has-children">Haschildren <span class = "open-menu-link">+</span>
<ul class="sub-menu">
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
</li>
<li>Careers</li>
<li>Contact</li>
</ul>
$(function() {
$('.open-menu-link').click(function(e){
console.log(e.target.parentNode.nextElementSibling);
console.log(e.target.parentNode.parentNode.children[1]);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li>Work</li>
<li class="menu-item-has-children">
Haschildren <span class="open-menu-link">+</span>
<ul class="sub-menu">
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
</li>
<li>Careers</li>
<li>Contact</li>
</ul>
There are couple of options:
$('.open-menu-link').click(function(e){
console.log(e.target.parentNode.nextElementSibling);
console.log(e.target.parentNode.parentNode.children[1]);
});
The <span class = "open-menu-link"> in your code has only one child i.e text node + this is the reason why e.currentTarget.children[1] is giving you undefined.
Coming to the dom traversal, you should start with node <li class="menu-item-has-children"> . Well that is what I can infer from your question.
You need to use preventDefault() because you'r class is a link. By clicking, it'll redirect you to the link.
$('.open-menu-link').click(function(e) {
console.log($(this).parent().next())
e.preventDefault()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li>Work
</li>
<li class="menu-item-has-children">
Haschildren <span class = "open-menu-link">+</span>
<ul class="sub-menu">
<li>Child 1
</li>
<li>Child 2
</li>
<li>Child 3
</li>
</ul>
</li>
<li>Careers
</li>
<li>Contact
</li>
</ul>

Hide and show list items of divs after nth item of direct child only

Say I have an unordered list, like so:
Demo
HTML Code :
<ul>
<li>One
<ul>
<li>on 1.1</li>
<li>on 1.2</li>
<li>on 1.3</li>
</ul>
</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
<li>One 1</li>
<li>Two 2</li>
<li>Three 3</li>
<li>Four 4</li>
<li>Five 5</li>
<li>One 11</li>
<li>Two 22</li>
<li>Three 33</li>
<li>Four 44</li>
<li>Five 55</li>
</ul>
<span class="show_more">see more</span>
Script File :
$('.nav_accordian').each(function(){
var max = 4
if ($(this).find('li').length > max) {
$(this).find('li:gt('+max+')').hide().end().append('<li class="sub_accordian"><span class="show_more">(see more)</span></li>');
$('.sub_accordian').click( function(){
$(this).siblings(':gt('+max+')').toggle();
if ( $('.show_more').length ) {
$(this).html('<span class="showMore">show More</span>');
}
else {
$(this).html('<span class="showMore">less More</span>');
};
});
};
});
i did for when i click on 'show more' it should be visible next five results of list items . Once every results loaded 'show more' text would be changed on 'less more'.
and when i clicked upon the 'less more' button first results result items should be visible other items would be hide.
The issue is the script is consider child list of li also
Giving a class to the list element you want to count on should resolve your problem :
<ul>
<li class="list__element">One
<ul>
<li>on 1.1</li>
<li>on 1.2</li>
<li>on 1.3</li>
</ul>
</li>
<li class="list__element">Two</li>
<li class="list__element">Three</li>
<li class="list__element">Four</li>
<li class="list__element">Five</li>
<li class="list__element">One 1</li>
<li class="list__element">Two 2</li>
<li class="list__element">Three 3</li>
<li class="list__element">Four 4</li>
<li class="list__element">Five 5</li>
<li class="list__element">One 11</li>
<li class="list__element">Two 22</li>
<li class="list__element">Three 33</li>
<li class="list__element">Four 44</li>
<li class="list__element">Five 55</li>
</ul>
<span class="show_more">see more</span>
And in your JS you would count then ".list__element", like so :
if ($(this).find('.list__element').length > max) {
...
}

Don't slideToggle all

I have a vertical sliding menu, that looks like this:
<ul class="menu">
<li>link</li>
<li>link</li>
<li class="more">link with submenu</li>
<ul class="submenu">
<li>sub link 1</li>
<li>sub link 2</li>
</ul>
<li class="more">link with submenu</li>
<ul class="submenu">
<li>sub link 1</li>
<li>sub link 2</li>
</ul>
<li>link</li>
<li>link</li>
</ul>
the jQuery is like this:
jQuery(document).ready(function($) {
$(".more").click(function() {
$(this).parent().children(".submenu").slideToggle(500); });
});
My problem is, when I click on a ".more", every ".submenu" is being slideToggle (Both opens)
How can I do, so it is only the correct submenu that is being slidetoggled?
Thank you.
Remove the call to .parent(). Also, your .submenu should be nested within the <li> to which it belongs, leaving you with the following jQuery:
$("li.more").on("click", function() {
$("ul.submenu", this).slideToggle(500);
});
And this markup:
<ul class="menu">
<li>link</li>
<li>link</li>
<li class="more">
link with submenu
<ul class="submenu">
<li>sub link 1</li>
<li>sub link 2</li>
</ul>
</li>
<li class="more">
link with submenu
<ul class="submenu">
<li>sub link 1</li>
<li>sub link 2</li>
</ul>
</li>
<li>link</li>
<li>link</li>
</ul>
this one?
$(this).next().eq(0).slideToggle(500); });

Categories

Resources