Toggle submenu and if child clicked go to page - javascript

I've built a simple toggle menu that when clicked once shows a list of child elements and if clicked again hides those visible elements.
If a child element is clicked however I want it to visit that page only I cant seem to get it working? Is it to do with my prevent Default?
// Language select in global nav
$('.sub-lang').on('click', function(e) {
if ($(this).hasClass('active') && $(e.target).parent().hasClass('active')) {
$(this).removeClass('active');
$(this).css('height', 'auto');
$(this).children('ul').hide();
} else {
$(this).addClass('active');
$(this).css('height', $(this).find('ul').height() + 65);
$(this).children('ul').show();
}
e.preventDefault();
});
Here is the JsFiddle

Why don't you simple transform your main menu element in paragraph tag ?
or you could put an # inside your main menu element, and delete prevent default.
In this way you don't need to prevent default on your main elements.
Although google.com doesn't load inside an iFrame, you could check this fiddle. It works.
Look at this (with # in the anchors) fiddle
HTML
<ul style=" ">
<li class="sub-lang">
English
<ul style="">
<li>International</li>
<li>UK & Ireland</li>
</ul>
</li>
<li class="sub-lang">
Espanol
<ul style="">
<li>Español</li>
<li>España</li>
</ul>
</li>
<li class="sub-lang">
Francais
<ul style="">
<li>Français</li>
<li>France</li>
</ul>
</li>
</ul>

Add this line before your code
$('.sub-lang > a').removeAttr('href');
Remove
e.preventDefault();
this should work fine

You should add one condition for that.
if($(e.target).parent().hasClass('sub-lang') )
It will allow you to click on submenu.
// Language select in global nav
$('.sub-lang').on('click', function(e) {
if($(e.target).parent().hasClass('sub-lang') ){
if ($(this).hasClass('active') && $(e.target).parent().hasClass('active')) {
$(this).removeClass('active');
$(this).css('height', 'auto');
$(this).children('ul').hide();
} else {
$(this).addClass('active');
$(this).css('height', $(this).find('ul').height() + 65);
$(this).children('ul').show();
}
e.preventDefault();
}
});
ul li ul {
display: none;
z-index: 2;
right: 0;
background-color: #fff;
width: 250px;
}
ul li.active ul {
display: block;
text-align:left;
background: #f1f1f1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul style=" ">
<li class="sub-lang">
English
<ul style="">
<li>International</li>
<li>UK & Ireland</li>
</ul>
</li>
<li class="sub-lang">
Español
<ul style="">
<li>España</li>
</ul>
</li>
<li class="sub-lang">
Français
<ul style="">
<li>France</li>
</ul>
</li>
</ul>
Working Fiddle
Hope it helps.

Here Check This Out.
Explaination.
Instead of delegating the event on the whole li, I bound the event to all the immediate <a> children of the li, and then prevent the propagation for that specific element. So we don't have to figure out how to stop the event propagation (click in our case) to the children element.
Also the JSFiddle may have loading external iframe problems, so check the solution out here.

I think you have to add stopPropagation in your inside list items.
$('.sub-lang ul li').on('click', function(e) {
e.stopPropagation();
});

Related

jQuery - Can't show dropdown list upon clicking a link

I have a header and am trying to create a drop-down menu without Bootstrap.
When I click on a link, I want the drop-down menu to appear. It's hidden by default. I tried using jQuery to show the list.
HTML
<div class="menu">
<div class="menu_center">
Products
<ul>
<li>Clothing</li>
<li>Stationary</li>
<li>Other
</ul>
Promotions
About Us
<ul>
<li>Philosophy</li>
<li>Our Suppliers</li>
<li>Contact</li>
</ul>
Your Cart:
<ul>
<li>Tech{Yourself} T-Shirt: Blue, Large - $19.95</li>
<li>Tech{Yourself} Owl Plush Toy - $19.95</li>
<li><b>Total: $39.90</b> <button class="js-check-out">Check Out</button></li>
</ul>
</div>
</div>
CSS
html body{
font-family:'Open Sans',sans-serif;
font-size:16px;
line-height:18px;
color:#000;
font-weight:400;
}
.menu_center a {
text-decoration: none;
}
jQuery
$(document).ready(function() {
$(".menu_center ul").hide();
$(".menu_center > a").on("click", function() {
$(this).children("ul").show();
});
});
http://jsfiddle.net/9ov9za3r/1/
Not sure why this isn't working.
The ul element is not a child of the a element, you would need to do:
$(this).next("ul").show();
jsfiddle
Replace this:
$(this).children("ul").show();
by this:
$(this).next("ul").slideToggle();
The ul is not the children, its the next element right after the a tag
and you might want to use toggle(), fadeToggle() or slideToggle() rather than just show() to be able to hide the menu again when u click on it after it appears
Here is the JSFiddle demo

Hide/show div in ul with javascript

Let me start by saying I know this is a duplicate, however I couldn't find a solution by looking through previous answers so I was hoping someone can explain what I'm doing wrong with this.
This is part of a menu output by a php script:
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0', 'mtk_div_submenu_0');">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
with the following as my script as per https://stackoverflow.com/a/11842992, which should show each submenu when hovering its parent container
function showMenu(a,b) {
$(a).hover(
function(){
$(b).show();
},
function(){
$(b).hide();
})
}
Javascript and CSS being my weak suits, could someone tell me where my problem is? I feel like onMouseOver doesn't work the way I would expect it to. However I am still learning to manipulate the DOM, please bear with me, thank you!
Edited to reflect missingno's suggestions
For simple scenarios, i'd rather stay away from using JS
Heres how
HTML
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0, mtk_div_submenu_0');">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
CSS
#mtk_main_menu:before,
#mtk_main_menu:after {
content:"";
display:table;
clear:both;
}
#mtk_main_menu {
*zoom:1;
}
#mtk_main_menu > li {
position:relative;
float:left;
}
#mtk_main_menu > li > div {
position:absolute;
left:-999px;
background:grey;
}
#mtk_main_menu > li:hover > div {
left:0;
}
That will do the trick
Fiddle: http://jsfiddle.net/Varinder/7pXSw/
Edit
If you really want to go the JS way - heres how:
HTML
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0, mtk_div_submenu_0');">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
CSS
#mtk_main_menu:before,
#mtk_main_menu:after {
content:"";
display:table;
clear:both;
}
#mtk_main_menu {
*zoom:1;
}
#mtk_main_menu > li {
position:relative;
float:left;
}
#mtk_main_menu > li > div {
position:absolute;
display:none;
/*left:-999px;*/
background:grey;
}
#mtk_main_menu > li:hover > div {
/*left:0;*/
}
JS
function showMenu( args ) {
var arguments = args.split(",");
var submenuWrapper = arguments[1].replace(" ", "");
var $subMenuWrapper = $( "#" + submenuWrapper );
$subMenuWrapper.show();
var $menuItem = $subMenuWrapper.closest("li");
$menuItem.on("mouseout", function() {
$subMenuWrapper.hide();
$(this).off("mouseout");
});
}
Fiddle: http://jsfiddle.net/Varinder/vnwy3/1/
You are calling the event handler with a single string parameter instead of two. Try changing
showMenu('mtk_submenu_0, mtk_div_submenu_0')
into
showMenu('mtk_submenu_0', 'mtk_div_submenu_0')
Additionally, inside your script you should use are using literal strings instead of using your parameters
//This looks for an element of class "a"
$("a").hover(
//This uses the contents of the `a` variable instead:
$(a).hover(
Finally, your function is using 'mtk_submenu_0' as a jquery selector. This searches for a class instead of an id. Change the selector to add a "#" on front or change your jquery logic to not need ids (for example, you could create selectors to search for the first div and ul descendants of the current element.
By doing what you are doing, every time the onMouseOver event is triggered, you're attaching the jQuery hover event. Each time you're attaching another listener.
Instead, initialize your event on document ready:
$(function () {
$("#tk_div_submenu_0").hover(
function(){
$("#mtk_submenu_0").show();
},
function(){
$("#mtk_submenu_0").hide();
})
);
});
That will initialize it when the document is ready, and it will initialize it once.
Then just remove your onMouseOver event from the HTML.
<li class="mtk_topmenu">Manager Options ... </li>
First, you're going the long way around the problem. jQuery has a built in toggle method that performs the show/hide for you. Secondly you're putting the hover call on the child element of the item you're trying to show on hover. Here's an updated version of your code:
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu(this,'mtk_div_submenu_0');">
Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
</ul>
JS:
function showMenu(a,b) {
var divStr = '#' + a.id + " div";
$(divStr).toggle();
}
I used the hover event on the LI element as it makes more sense in this case.
Here it is in a fiddle: http://jsfiddle.net/3Ecrq/
One thing I find strange about your code is that the first div you mention, mtk_submenu_0, is inside the div you are showing / hiding, mtk_div_submenu_0. Once you hide the outer div, the inner div cannot be 'hovered over', thus preventing it from being shown again.
To ensure the inner div does not get hidden, try something like this:
HTML:
<ul id="mtk_main_menu">
<li class="mtk_topmenu">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
Javascript:
$(document).ready(function() {
$('.mtk_topmenu').hover(
function() {
$('#mtk_div_submenu_0').show();
},
function() {
$('#mtk_div_submenu_0').hide();
});
});
Because of your line:
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0', 'mtk_div_submenu_0');">
I assumed you were looking to have the mtk_div_submenu_0 div show / hide whenever the text Manager Options is moused over. Hopefully this helps!

how to find div with class inside in li with jquery

i have this HTML code
<ul>
<li>test1
<div class="sub-menu">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
</li>
<li>test2</li>
<li>test3</li>
<li>test4
<div class="sub-menu">
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
</div>
</li>
</ul>
that div.sub-menu has hidden in css.
i want when hover in a find div that inside in parent li and show it,
i try in jquery but when hover in a tag show two sub-menu div,
i want when hover in test1 show div.sub-menu that have 1,2,3,4
and when hover in test4 show div.sub-menu that have a,b,c,d
You can attach a handler for the mouseenter and mouseleave events that manipulates the associated sub-menu, for example like this:
$(document)
.on("mouseenter", "ul > li > a", function() {
$(this).siblings(".sub-menu").show();
})
.on("mouseleave", "ul > li", function() {
$(this).children("a").next(".sub-menu").hide();
});
This snippet installs delegated event handlers that show and hide the sub-menus -- note that the "hide" trigger is different from the "show" trigger because we don't want the menu to disappear as soon as the mouse pointer moves off the anchor. See it in action.
However depending on the desired result you might also be able to do this with pure CSS, e.g.
ul > li > a + .sub-menu { display: none }
ul > li:hover > a + .sub-menu { display: inline-block }
See it in action.
Both versions are structured so that they work also for nested sub-menus.
Simply hide/show the sub-menu on mouseover/mouseout:
Javascript
$("li").mouseover(function(){
$("ul", this).show();
});
$("li").mouseout(function(){
$("ul", this).hide();
});
JS Fiddle: http://jsfiddle.net/EDufY/
If You want to display menu on hover effect of li then i think u don't need javascript.
if u change css then it is posiible.
write your css like.
.sub-menu
{
display:none;
}
li:hover .sub-menu
{
display:block
}
And you have multilevel menu then give them id and repate above procedure
Try this with slide effect, http://jsfiddle.net/SmtQf/1/
$(function () {
$('ul li').hover(
function () {
$('.sub-menu', this).stop(true, true).slideDown(); /*slideDown the subitems on mouseover*/
}, function () {
$('.sub-menu', this).stop(true, true).slideUp(); /*slideUp the subitems on mouseout*/
});
});

jQuery click event target padding

I am trying to register clicks using jQuery and there seems to be an issue with the padding.
Here's a jsFiddle to help with seeing it.
I'm trying to get clicks on an open menu to do nothing while clicks anywhere else will close all the menus. It works well, but the biggest problem is if you click above the <li> but still within the <div> it fails. It seems to be that the padding isn't counted as part of the div or something.
The code is here as well:
HTML
Main
<div id="mainMenu" class="menu">
<ul>
<li class="menuItem">item 1
</li>
<li class="menuItem">item 2
</li>
<li class="menuItem">item 3
</li>
<li class="menuItem">item 4
</li>
<li class="menuItem">item 5
</li>
</ul>
</div>
Menu 2
<div id="menuTwo" class="menu">
<ul>
<li class="menuItem">item 1
</li>
<li class="menuItem">item 2
</li>
<li class="menuItem">item 3
</li>
<li class="menuItem">item 4
</li>
<li class="menuItem">item 5
</li>
</ul>
</div>
JS
$(document).ready(function () {
//Attach a handler to the document for clicks.
$(document).on("click", function (e) {
//Get the click's target and convert to $ object.
$target = $(e.target);
//Find out if the click occurred on a menu.
$parents = $target.parents(".menu");
if ($parents.length > 0) {
console.log(["Menu click", e]);
return;
} else {
//If it wasn't on a menu close the open menu.
console.log(["Non-menu click", e]);
$('.menu').hide();
}
});
//Handle showing the menu.
$('.menuLink').on("click", function (e) {
//Close all other menus.
$('.menu').hide();
console.log("Started");
e.stopPropagation();
e.preventDefault();
var targetMenu = $(e.target).attr("href");
$(targetMenu).show();
});
});
CSS
#mainMenu {
background-color: lightblue;
}
#menuTwo {
background-color: lightgreen;
}
.menu {
display: none;
border: 1px solid black;
}
Your problem is with this line:
$parents = $target.parents(".menu");
Change it to this:
$parents = $target.closest(".menu");
The div doesn't have a parent with the class .menu, so if you click that, it doesn't find anything. closest includes the selected element in the search.
http://jsfiddle.net/ecnGr/
Use closest to solve your issue
$parents = $target.closest(".menu");
If you still want to use parents then add an extra check to see if the clicked element is the div.
if ($parents.length > 0 || $target.is('.menu')) {
Check Fiddle
The problem with your code was that parents method does not include the element in question. So you have to do that check explicitly, or use closest which includes the element in question as well.
You can just consume all clicks on the menu, which will do the trick.
$(document).ready(function () {
//Attach a handler to the document for clicks.
$(document).on("click", function (e) {
$('.menu').hide();
});
$('.menuLink').on("click", function (e) {
$('.menu').hide();
e.stopPropagation();
e.preventDefault();
var targetMenu = $(e.target).attr("href");
$(targetMenu).show();
});
//Handle showing the menu.
$('.menu').on("click", function (e) {
e.stopPropagation();
});
});
http://jsfiddle.net/MightyPork/UCwAt/8/

Active link (the css?)

i've got a problem with the CSS. Normally I can get it right, but now it's just not working for me.
Got the menu-code
<nav>
<ul class="ca-menua">
<li class="home"><div class="ca-icona">O</div><span>Home</span>
</li>
<li class="info"><div class="ca-icona">e</div><span>Info</span>
</li>
<li class="komp"><div class="ca-icona">S</div><span>Kompetencer</span>
</li>
<li class="cases"><div class="ca-icona">F</div><span>Cases</span>
</li>
<li class="kontakt"><div class="ca-icona">#</div><span>Kontakt</span>
</li>
</ul>
</nav>
The i've got the javascript which add's the active class.
<script type="text/javascript">
$(document).ready(function(){
$('.home a.tooltip').addClass('active');
});
</script>
<script type="text/javascript">
$(function() {
$('a.tooltip').click(function(e) {
var $this = $(this);
$("#nav").load($this.attr('href'));
$('a.tooltip').removeClass('active');
$(this).addClass('active');
// prevent default link click
e.preventDefault();
})
});
</script>
This works fine, and adds the class, but I just can't get the CSS right!
I need some help with a prob. small problem.
The website link is: HERE
THE CSS:
a.tooltop.active{
color: #f3cb12;
font-size: 50px;
}
Just add the div part into a.tooltip.active selector so you get something like this:
a.tooltip.active div {
color: #F3CB12;
font-size: 50px;
}
I have assumed that you are trying to get the icon bigger and highlighted if the menu item is active. The problem is that it is not the anchor that should be getting new styles, but the child div element.

Categories

Resources