So I made my own right click context menu, and I have expandable options on the right click menu when you hover over them. I want the expanded menu to close if the mouse leaves the right click menu so I used the following code:
$('ul').live('mouseout', function(event) {
// close code here
});
But the problem is the event gets called every time I move the mouse onto any of the <li> elements.
How do???
$('ul')
That means all the ul elements. May be you can give it a class (or an id) and do
$('ul.theClass')
Or
$('#ulId')
You might want to change your the code to not bind 'ul' to mouseout because the 'ul' tag would wrap the 'li' tags else nothing you do would work.
A solution for this is that you change menu option title to a div or something else while retaining the menu options as 'ul' 'li' tags
You should try in li try any one of this
$('ul li.classnameforli').bind('mouseout','mouseleave' function(event) {
// close code here
});
Or
$('ul li.classnameforli').live('mouseout' function(event) {
// close code here
});
Related
Sorry for the question title, I really didn't know how to summarise it a short description.
Essentially I have got a <ul> which has my navigation links. However in one of the <li> links is my custom dropdown shopping basket to give the user a preview of their items.
Now when I hover over the element , I want it to change the basket from display:none to display:block making it visible. But with my code, as soon as I leave the hovered element to click on an item. The dropdown disappears because I'm no longer hovering over the element I defined in my jQuery hover function.
For example (quick dummy code)
$('.hover-on-me').hover(function(){
$('.hover-open').show();
},function(){
//This right here hides the dropdown
$('.hover-open').hide();
});
Now I'm not the bets at javascript/jQuery. I have tried to say in the function, if the mouse is still on the navigation bar , don't hide it or if the mouse is on the shopping basket then don't hide it. I thought this would let me move from the hover element, past the navigation bar and onto the drop down menu but it doesn't work. as the element then stays open and doesn't close when i leave the area.
Here is a simple jsfiddle demonstrating my problem.
Thanks!
I think there is mistake in your class name only.
jQuery Code :-
$('.hover-on-me').hover(function(){
$(this).parent("li").addClass("active");
}, function(){
$(this).parent("li").removeClass("active");
});
Add this to you CSS Code :-
ul li.active{display:inline-block;}
ul li.active .hover-open, ul li .hover-open:hover{display:block;}
Can you please try these.
the hover syntax will look like this.. $(selector).hover(inFunction,outFunction)
and try to modify your script like this..
$('.hover-on-me').hover(
function(){
$('.hover-open').show();
},
function(){
if(!$('ul').is(":hover") || !$('.hover-open').is(":hover")){
$('.hover-open').hide();
}
}
);
OR
use mouse event function..
$( ".hover-on-me" )
.mouseenter(function() {
$('.hover-open').show();
});
$( ".hover-open" )
.mouseleave(function() {
$('.hover-open').hide();
});
for further details refer here..https://api.jquery.com/hover/#hover2 and https://api.jquery.com/category/events/mouse-events/
I've got an accordion menu which toggles on click.
This is the code :
$('ul.internal-nav-list li ').on('click', function () {
$(this).find('.internal-sub-list li ').toggle();
});
And the markup looks like this:
<div id="internal-nav">
<ul class="internal-nav-list">
<li><a>products</a>
<ul class="internal-sub-list">
<li>product1</li>
<li><a href="product2.aspx" >product2</a></li>
<li>product3</li>
</ul>
</li>
</ul>
</div>
Now I'm trying to enable that when an li element from the menu is open and the user clicks on another li, the open one will automatically close. Can anybody give me a suggestion on how to do this?
I'v I'm interpreting what you want correctly, try this:
var mainlis = $('.internal.nav.list > li'); // cache selector
mainlis.on('click', function(e) {
e.preventDefault();
var me = $(this);
mainlis.hide();
me.show();
});
The other existing answers come close, but it seems like what you want to do is hide the children of other menu items when the main menu items are clicked. If that is the case, the following will do:
$('.internal-nav-list > li > a').on('click', function () {
var $thisLi = $(this).parents('li');
$thisLi.siblings().find('.internal-sub-list').hide();
$thisLi.find('.internal-sub-list').show();
});
Note the first selector: this restricts the click handler to just the anchor, not the entire li. That means if they click on a child of the currently displayed main menu item, the function will not be called. That way you don't risk having a flicker as the click the submenu items...
In the handler itself, it traverses back to the parent li, finds its siblings and hides their children. Then is shows the submenu for the currently selected main menu.
Note that I took the liberty of hiding the entire ul of the non-selected menus; this should be faster than hiding each child. Perhaps not significantly, but I find it's best practice to perform these kinds of actions on the container rather than all children of the container.
The simplest solution is to close all lielements and open only the one clicked
$('ul.internal-nav-list > li').on('click', function () {
$(this).siblings('li').slideUp();
$(this).slideDown();
});
EDIT As Morfie pointed out, only the immediate children li of the internal-nav-list should be clickable, thus the > operator is used.
Thanks for the suggestions- I got it working this way in the end (in case it helps anyone)
$('ul.internal-nav-list li').on('click', function () {
$close = $(this).find('.internal-sub-list li ').toggle();
$('.internal-sub-list li').not($close).hide()
});
I have a accordion menu which have for each parent menu a icon, and this icon is animated with css transition and transform. I added a class with a if condition to the click event. The problem is that when I click for example on Menu1, the icon animation does very well, but if I click directly on Menu2, the menu2 dropdown appear but icon from the menu1 don't take his original position.
This problem applies to each icon in each menu/submenu, I thinks that I have a mistake in my code.
$(document).ready(function() {
// Icons effect
$('#mw_nav .toggle').click(function() {
if($(this).hasClass('rotate_close'))
{
$(this).addClass('rotate_open').removeClass('rotate_close');
}
else {
$(this).addClass('rotate_close').removeClass('rotate_open');
}
});
// Toggle Menu Items
$(function () {
$("#m_nav > ul ul").hide();
$('#m_nav .toggle').click(function (e) {
e.preventDefault();
e.stopPropagation();
var $parentli = $(this).closest('li');
$parentli.siblings('li').find('ul:visible').slideToggle(400);
$parentli.find('> ul').stop().slideToggle(400);
$(this).remove;
});
});
});
FIDDLE
Any help would be appreciated
There are 2 issues I see with your code. The first is a recommendation to NOT have $(function() { // your code }) inside of $(document).ready(). $(function() {}) is actually just shorthand for $(document).ready() so you are adding code you do not need.
The second is an issue with your logic.
$('#mw_nav .toggle') and $('#m_nav .toggle') click listeners are essentially adding a click listener on the same exact element, but both run different logic. When the $('#mw_nav .toggle') click listener is getting called it checks for a class to exist to decide what class it needs to remove and add. When $('#m_nav .toggle') click listener is getting called it calls a slideToggle function on the current nested <ul> regardless if another menu is opened or closed and there is no check in place of whether or not the rotate_open/rotate_close classes exist allowing for the classes to get swapped. There is no relation between the swapping of rotate_open/rotate_close classes and the logic that slideToggles <ul> up/down.
UPDATE
I have edited your code and made updates that will now work seen here: https://jsfiddle.net/vhfn0q5a/9/
I have added a class of .top_level to the top level items in your HTML. I use this as a way of differentiating the top level <li> from the sub menus. Next, at the end of the click event listener I check to see if the .toggle element clicked is a top level element, if so I target all top level elements that are not the current selected and make sure they have the .rotate_close class.
$(function() {}) shorthand reference
Use this code in your first click handler:
$('#mw_nav .toggle').click(function() {
$(this).toggleClass('rotate_close rotate_open');
if ($('#mw_nav .toggle').not(this).hasClass('rotate_open')) {
$('#mw_nav .toggle').not(this).removeClass('rotate_open').addClass('rotate_close');
}
});
I've updated your FIDDLE with an working example.
Cheers!
Ok... So I have this drop down menu working as I'd like... however I'm trying to figure out how to revert the function back to it's original state after a menu item is clicked.
So first when you trigger the function it does & works great the following:
It swaps out .menu_hide and .lockscreen for .menu_show and .lockscreen_on.
// show and hide mobile menu
$('#triggerMobileMenu').click(function(e) {
e.preventDefault();
// Toggle all 4 classes off or on
$('#mobileMenu').toggleClass('menu_hide menu_show');
$('#mobileScreen').toggleClass('lockscreen_off lockscreen_on');
But now I'm trying to add another piece that says once a menu item is clicked, close the menu and swap the classes back to their original state from .menu_show and .lockscreen_on, to .menu_hide and .lockscreen_off.
$('#mobileMenu ul li a').on('click',function(){
$('#mobileMenu').toggleClass('menu_show menu_hide')({ autoCloseOnClick: true });
$('#mobileScreen').toggleClass('lockscreen_on lockscreen_off')({ autoCloseOnClick: true });
});
});
I should also note that on the same page a scroll to id# may be happening vs just simply taking you to the new url/page. Either case will happen though.
I think that you're making this too complicated. Use the same event handler for both a#triggerMobileMenu and ul#mobileMenu li a since you're having them do the same thing (toggle the visibility of the menu and another element).
$('a#triggerMobileMenu, ul#mobileMenu li a').on('click', function(evt){
evt.preventDefault();
$('#mobileMenu').toggleClass('menu_hide menu_show');
$('#mobileScreen').toggleClass('lockscreen_off lockscreen_on');
});
If you need to know which element was clicked in the event handler, evt.target is available:
if( $(evt.target).is($('a#triggerMobileMenu')) ) {
// do stuff
}
See http://jsfiddle.net/Mph6t/3/
I think it is working as intended. I had to fix some id names that may have been switched in the translation to jsfiddle. Here's a working one as far as I can tell. This leaves the somename2 div still showing. I assume that is going to be blank and just for locking the screen right?
I also changed the link to a new tab for testing purposes. FYI.
Relevant changes are:
$('#somename1 ul li a').on('click',function(){
$('#somename1').toggleClass('menu_show menu_hide')({ autoCloseOnClick: true });
$('#somename2').toggleClass('lockscreen_on lockscreen_off')({ autoCloseOnClick: true });
});
I have created a collapsible menu in JQuery with the help of some coding I've found around this site.
And everything work. But now it's time for me to understand how and why it works.
The JQuery:
jQuery(document).ready(function($) {
var submenu = $('.submenu').hide();
$('.open').click(function() {
$this = $(this);
$target = $this.parent().next();
if(!$this.hasClass('close')){
$('.open').removeClass('close');
submenu.slideUp();
$this.addClass('close');
$target.slideDown();
}else{
$target.slideUp();
$this.removeClass('close');
}
});
});
The HTML and CSS are in here: JSFIDDLE!
Can someone break the code down for me, and explain what it does.
I know that it hides my .submenu class when the page loads.
And when I click the class .open the .submenu. slides down
But then I am a bit lost to what it does with my .close class.
Thanks in advance!
No problems :)
Let's start with this:
jQuery(document).ready(function($){});
this wraps around all jQuery code. it defines an anonymous function and attaches it to the event $(document).ready meaning - this code runs only after the entire DOM is loaded. This is needed because if the following code will run before the elements were loaded it will have no effect on them,
var submenu = $('.submenu').hide();
This line picks all elements with class="submenu", hides them - and returns an array of all submenus to the submenu variable. The rest of the explanation will be commented on each line:
$('.open').click(function() { // the following code will run if you click an element with class="open"
$this = $(this); // $this will hold the element you clicked
$target = $this.parent().next(); // $target will hold the next element (relevant single submenu)
if(!$this.hasClass('close')){ // if the current element is open (marked by class="closed")
$('.open').removeClass('close'); // remove the "close" class from all main menu items
submenu.slideUp(); // close all submenus
$this.addClass('close'); // add "close" class only to the clicked main menu item
$target.slideDown(); // open the correct submenu (the element after the clicked main menu item)
}else{ // if current submenu is already open
$target.slideUp(); // close it
$this.removeClass('close'); // remove class "close" from the main menu item.
}
});
When user clicks on a menu group, you need to consider two cases:
The clicked menu group is closed (i.e. it doesn't have the close class)
!$this.hasClass('close')
If so, you first have to close all open menus, and set their class accordingly:
$('.open').removeClass('close');
submenu.slideUp();
Then you can expand the clicked menu group, and mark it as currently open:
$this.addClass('close');
$target.slideDown();
The clicked menu group is already open. The only thing that needs to be done in that case is closing the menu:
$target.slideUp();
$this.removeClass('close');