jQuery .hover() is driving me crazy - javascript

I have a project that uses drop-down menus that are nested ul's, like so:
<ul id="nav">
<li id="thome" class="navtab">
HOME
<ul id="subnav_home" class="submenu">
<li>Dashboard</li>
<li>SMS</li>
<li>Email</li>
<li>Twitter</li>
</ul>
</li>
</ul>
Using jQuery, I've added a .hover() to the .navtab li that .show()s the .submenu ul. The problem is that when the cursor moves into the new ul, the .hover()-out for the .navtab fires, .hide()ing the sub-menu, despite the fact that I have the height of the li so that it entirely wraps the .submenu ul.
I've tried adding a delay to the .hide(), but if you pass your cursor over the navtab bar quickly, you get all of the sub-menus at once.
Any solutions for me? Here's the relevant JavaScript. The hide() function is identical to .show() except that it shrinks the height and hides the ul (obviously).
$('.navtab').hover(
function(){
tabShowSubnav($(this).attr('id'));
},
function(){
tabHideSubnav($(this).attr('id'));
});
function tabShowSubnav(menu){
var sb = '#' + menu + ' > .submenu';
var tb = '#' + menu;
$('.navtab').each(function(){
if (!$(this).hasClass('current_page')){
$(tb).addClass('nav_hover');
}
});
$(tb).css('height','239px');
$(sb).show();
}

$('.navtab').hover(
function() {
$(this).children(".submenu").show().children('current_page').addClass("nav_hover");
},
function() {
});
$(".submenu").mouseout(function(){
$(this).hide();
});

$('.navtab').hover(
function() {
$(this).children(".submenu").show().children('.current_page').addClass("nav_hover");
},
function() {
$(this).children(".submenu").hide();
});
This worked for me.

I finally had to go with the jQuery plugin hoverIntent, that ignores children for the purpose of mouseout.

Related

RemoveClass and AddClass not working

I think this may be because these elements didn't originally have the DOM element. I have tried using events and then a propagation tool, but it's still not working :(
I want it so that when you click one of the items, it removes the underline from all items, and then adds it to the item that you just clicked, but in this case it keeps it underlined. To test just use the fiddle link and click on the first "A", and then the second bigger "A"
(JSFiddle)
$(document).ready(function() {
$("li.big").on("click", function(e) {
$("li>a.underline").removeClass("underline");
$("li.big").addClass("underline");
e.stopPropagation();
});
$("li.default").on("click", function(e) {
$("li>a.underline").removeClass("underline");
$("li.default").addClass("underline");
e.stopPropagation();
});
});
a {
text-decoration: none;
}
.underline {
text-decoration: underline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav navbar-nav">
<li>
<div class="raisetext">Raise Text:</div>
</li>
<li class="default">A
</li>
<li class="big">A
</li>
<li class="bigger">A
</li>
</ul>
To add to Sushils answer, it sounded like the anchors were appended. So, just in case the anchor tags were dynamically appended to the page:
$(document).ready(function() {
$("li").on("click","a", function() {
$("li > a").removeClass("underline");
$(this).addClass("underline");
});
});
you can simply use $('a').on('click', function(){ instead of the li.big and li.default since they're all links.
try this
$(document).ready(function() {
$('a').on('click', function(){
$('a').removeClass('underline');
$(this).addClass('underline');
});
});
here's a working JSFIDDLE
note: this will apply to all the links on the page. if you don't wan't it to apply to all the links, then you can use a class.

How do I make a .hover div stay open while the mouseover is still on the parent?

First things first, a fiddle: http://jsfiddle.net/d7wfv8w8/
I have a navbar with a logo, search form and a Categories link. When somebody moves over it with the mouse, it should open the wrapper-categories div, which is display: none; by default.
I got it working, except the div is closing when you then move the mouse over the div that opened. I thought I could get it to stay open if I used .navbar .toggle to tell it that the parent is .navbar and it should stay open as long as the mouse is anywhere over that parent div.
How can I achieve this?
Here is my HTML:
<div class="navbar">
<div class="wrapper-header">
<ul>
<li class="">Logo Here</li>
<li class="">Search Here</li>
<li class="">Categories</li>
</ul>
</div>
<div class="wrapper-categories">
Categories Here
</div>
</div>
And the jQuery:
$(".navbar .toggle").hover(function (event){
event.preventDefault();
$(".wrapper-categories").slideToggle("fast");
});
You can achieve this by binding the hover function to the element wrapping both wrapper-header and wrapper-catagories. This will cause the hoverOut to only be called when it leaves the wrapper for both elements. Keeping both of your required divs open.
Fiddle: http://jsfiddle.net/d7wfv8w8/5/
Late to the party but change your class' to ID's and give this a go. Works for me.
$(document).ready(function(){
$( "#toggle" ).hover(
function() {
$( "#wrapper-categories" ).slideDown({
left: "+=50",
height: "toggle"
}, 500, function() {
// Animation complete.
});
}
);
var inArr = {toggle:false, wrapper-categories:false};
$('#toggle, #wrapper-categories').mouseover(function(){
inArr [$(this).attr('id')] = true;
});
$('#toggle, #wrapper-categories').mouseout(function(){
inArr [$(this).attr('id')] = false;
setTimeout(function(){
if(!inArr.toggle && !inArr.wrapper-categories) {
$('#navArea').slideUp(500);
}
},100);
});
});

Prevent a dropdown ul to reappear on mouseenter while fading it out

Basically what I have is a dropdown menu, when I click on the #default li a dropdown ul appears containing two list items. The idea is that when you move your mouse out of the dropdown ul or when you click on a .sub-option, the dropdown ul will fadeOut. This works, however, if I click on a .sub-option and the dropdown ul starts to fade, and then hover over the ul before the fadeOut is done, it will stop fading and the ul will reappear.. How do I prevent this from happening? I want nothing to happen when you move your mouse over the ul when it's fading out.
I tried adding a mouseenter event that checks if the ul is being animated but I'm not sure what exactly to put inside of this function, a simple return did not work. Any ideas on how to alter my code below so that it behaves properly?
The dropdown:
<ul id="sort-options">
<li id="default"><span>A-Ö</span>
<ul>
<li class="sub-options">A-Ö</li>
<li class="sub-options">Ö-A</li>
</ul>
</li>
</ul>
The script that toggles the dropdown:
$('#default').on('click', function() {
$('#default ul').stop().fadeToggle();
});
$('#default').on('mouseleave', function() {
$('#default ul').stop().fadeOut();
});
$('#default').on('mouseenter', function() {
if ($('#default ul').is(':animated')) {
return;
}
});
jsBin demo
$('#default').on('click', function(e) {
$('ul', this).stop().fadeToggle();
}).on('mouseleave', function() {
$('ul', this).fadeOut(); /* don't use .stop() */
});
the above works cause the .stop() used on the click event will stop any ongoing animations (the mouseleave fadeOut() which happens once the elements start to fadeToggle) and win! :)
Otherwise you need to stop the click bubble up the DOM tree and use:
jsBin demo using event.stopPropagation
$('#default').on('click', function() {
$('ul', this).stop().fadeToggle();
}).on('mouseleave', function() {
$('ul', this).stop().fadeOut(); // use .stop() but the issue will appear
});
$('#default li').on('click', function(e) {
e.stopPropagation(); // so dont let #default register any inner LI clicks
});

Using javascript function parameters to show jquery tabs

Actually I am trying to do jquery tabs. I have written a code that needs rework and probably better ways to implement. I think I could use function arguments to achieve this, but I am not sure. Can somebody tell me how to achieve this in a better way. Though my code works but I think it is rudimentary. I would also like only one tab to display a background color if this is active.
http://jsfiddle.net/5nB4P/
HTML:
<div id="nav">
<ul>
<li>First Tab</li>
<li>Second Tab</li>
<li>Third Tab</li>
</ul>
</div>
<div id="content">
<div class="tabs first">First Div content</div>
<div class="tabs">Second Div content</div>
<div class="tabs">Third Div content</div>
</div>
Script:
$(function() {
$("li :eq(0)").click(function() {
$("li").css("background","none");
$(this).css("background","red");
$(".tabs:gt(0)").hide();
$(".tabs:eq(0)").show();
})
$("li :eq(1)").click(function() {
$("li").css("background","none");
$(this).css("background","red");
$(this).css("background","red")
$(".tabs:gt(1), .tabs:lt(1)").hide();
$(".tabs:eq(1)").show();
})
$("li :eq(2)").click(function() {
$("li").css("background","none");
$(this).css("background","red");
$(".tabs:lt(2)").hide();
$(".tabs:eq(2)").show();
})
})
There is a much better way to achieve this. Here you go
$(function() {
$("li").click(function() {
$(this).css("background","red").siblings().css("background","none");
$(".tabs").hide().eq($(this).index()).show();
return false;
});
})
Working Demo
As #Niels mentioned for setting the background style you can have a dedicated class(active) and add/remove this class instead of setting the inline sytle.
FYI..In the above code $(this).index() gives the position of the first element within the jQuery object relative to its sibling elements
CSS:
.active {
background-color:red;
}
JQuery:
$('li').click(function(){
$this = $(this);
$this.addClass('active').siblings().removeClass('active');
$('.tabs:eq(' + $this.index() + ')').show().siblings().hide();
});
Here is a demo: http://jsfiddle.net/5nB4P/6/
Here is the way that I updated this to make it smaller and I believe to be more effective and easier to use:
http://jsfiddle.net/5nB4P/7/
Code:
$("#nav ul li").click(function(){
var id = $(this).attr("rel");
$("#nav ul li").each(function(){
$(this).removeClass("active");
});
$(this).addClass("active");
$("#content div").each(function(){
$(this).hide();
});
$("#"+id).show();
});
Do you mean this? http://jsfiddle.net/tsukasa1989/5nB4P/1/
$(function() {
$("#nav li").click(function(){
// Handle active status
$(this).addClass("active").siblings().removeClass("active");
// Show the tab at the index of the LI
$(".tabs").hide().eq($(this).index()).show();
})
// Don't forget to set first tab as active one at start
.eq(0).addClass("active");
})
If you want to style the active tab use
#nav li.active{}
My approach doesn't use arguments, but HTML class and id references to shorten things: http://jsfiddle.net/ZScGF/1/

Trying to use jQuery's .addClass method with navigation

i have a Nav wherein i'm attempting to use jQuery's addClass method to set the link color of the last clicked link. problem is then i have to use removeClass on all other links in the Nav. that's what i'm having trouble with.
I have written the code in a naive way, but know this is not good programming. below is the code with style sheet ref.
jQuery('#shop-nav').click(function(){
jQuery("#shop-nav").addClass("clicked");
jQuery("#art-nav").removeClass("clicked");
jQuery("#obj-nav").removeClass("clicked");
jQuery("#acc-nav").removeClass("clicked");
});
jQuery('#art-nav').click(function(){
jQuery("#art-nav").addClass("clicked");
jQuery("#shop-nav").removeClass("clicked");
jQuery("#obj-nav").removeClass("clicked");
jQuery("#acc-nav").removeClass("clicked");
});
etc. etc!
the HTML is
<div id="nav-cell-1" class="grid f-cell nav-cell">
<ul id="main-nav" class="nav clearfix">
<li>Shop
<ul id="shop-cats">
<li>Art</li>
<li>•</li>
<li>Objects</li>
<li>•</li>
<li>Accessories</li>
</ul>
</li>
</ul>
</div>
CSS:
a:link, a:visited {color:#cfb199;text-decoration:none} /* official this color:#9d9fa1; work color: #222*/
a:active, a:hover {color:#9d9fa1;text-decoration:none} /* old color:#9d9fa1; */ /* official color:#cfb199; work color: #f00*/
a:link.clicked, a:visited.clicked {color:green;text-decoration:underline}
a demo site is here:
http://www.tomcarden.net/birdycitynav/partial-nav-demo.html
I did solve part of the problem by using the this reference, but this do not include the .removeClass part.
jQuery('#shop-cats>li>a').click(function(){
jQuery(this).addClass("clicked");
});
Or this one works more like your site:
$('.nav a').click(function(){
$('.nav a').removeClass('clicked');
$(this).toggleClass('clicked');
});
test it here:
http://www.jsfiddle.net/mjYq3/18/
Try this to toggle the class:
var navs = jQuery('#shop-nav,#art-nav, #obj-nav, #acc-nav');
navs.click(function(){
navs.removeClass("clicked");
$(this).addClass("clicked");
});
Untested
jQuery('#shop-cats>li>a').click(function(){
$this = jQuery(this);
$this.parent().children('a').removeClass('clicked');
$this.addClass("clicked");
});
You can first remove all the clicked classes then add it back to just the one that was clicked.
jQuery('#shop-cats>li>a').click(function(){
jQuery('#shop-cats>li>a').removeClass("clicked")
jQuery(this).addClass("clicked");
});
This should work:
$('#main-nav a').click(function() {
$('#main-nav a').not(this).removeClass('clicked');
$(this).addClass('clicked');
});
On the basis that you apparently want to do this for all links that are descendents of #main-nav, and not just those that are in the inner <ul> list.

Categories