JQuery drop down, remain down while hover over drop down - javascript

I setup a jquery dropdown menu that works perfect. It drops down when a user rolls over a link. The problem is that when the user rolls over the content area of the drop down menu, it slides back up. I need to set up the code so that the slidedown box remains in the down position while the user's cursor is still over it.
Here is my HTML:
<ul id="tabnav">
<li class="tab2">My Leases</li>
</ul>
<div id="leases">
<!-- slide down content here -->
</div>
JS Trigger:
<script type="text/javascript">
$(document).ready(function(){
$(".btn-slide").hover(function(){
$("#leases").slideToggle("medium");
$(this).toggleClass("active");
return false;
});
});
</script>
Any ideas?
EDIT: Here is a link to page in question: http://designvillain.com/testbed/600/601.html

I'm not sure if this is what you want, but I'll just drop it here. It waits 500ms before sliding up #leases, and only when appropriate
var isMousedOver;
var hideDropdown = function(a) {
setTimeout( function() {
if (isMousedOver) return;
$("#leases").slideUp("medium");
$(a).removeClass("active");
}, 500);
}
$(".btn-slide").hover(
function(){
$("#leases").stop(true,true).slideDown("medium");
isMousedOver = true;
$(".btn-slide").removeClass("active");
$(this).addClass("active");
var that = this;
$("#leases").data("mouseoutfn", function() { hideDropdown(that) });
},
function(){
isMousedOver = false;
hideDropdown(this);
}
);
$("#leases").hover(
function() {
isMousedOver = true;
},
function() {
isMousedOver = false;
$(this).data("mouseoutfn")();
}
);
Here's a demo: http://jsfiddle.net/mMRZc/

The .hover() binds two events, mouseenter and mouseleave.
I would instead go granular and use the mouseenter() on the .btn-slide and the mouseleave() on the .leases
$(function()
{
$(".btn-slide").mouseenter(function(){
$("#leases").slideToggle("medium");
$(this).toggleClass("active");
});
$("#leases").mouseleave(function(){
$(".btn-slide").toggleClass("active");
$(this).slideToggle("medium");
});
});
EDIT: Note, if the mouse never enters the #leases div, it will not get the mouseleave, and you may need to consider that.
EDIT2: fix my bad finger typing of funciton to function

I assume the div is hidden on page load and you want it to show when you hover over the link? Change toggle to down...
$(document).ready(function(){
$("#leases").hide();
$(".btn-slide").hover(function(){
$("#leases").slideDown("medium");
$(this).toggleClass("active");
return false;
});
});
Does it need to slide back up sometime?

Related

layout / masonry - delayed layout adjustment - one click behind

Ok, so here is the problem
https://jsfiddle.net/yq7f1a63/1/
Here is my code:
$(function () {
$('.content').hide();
$('a.read').click(function () {
$(this).parent('.excerpt').hide();
$(this).closest('li').find('.content').slideDown('fast');
$('ul').masonry('layout');
return false;
});
$('a.read-less').click(function () {
$(this).parent('.content').slideUp('fast');
$(this).closest('li').find('.excerpt').show();
$('ul').masonry('layout');
return false;
});
});
$('ul').masonry({
itemSelector: 'li',
});
I have several masonry items with text inside. When clicking 'read more' it reveals more text (swaps .excerpt for .content).
I am using the layout method to adjust the grid when each item is clicked to reveal more, but for some reason it's one click behind. So for example I click read more on the first item and it goes wrong, but then I click read more for the next item and it adjusts to what the first item layout should have been, and so on!
Any ideas people?! Thanks in advance :-)
You need to adjust the grid after slideDown() or slideUp() finishes. So, add that code to their complete callback functions.
$(function () {
$('.content').hide();
$('a.read').click(function () {
$(this).parent('.excerpt').hide();
$(this).closest('li').find('.content').slideDown('fast',function(){
$('ul').masonry('layout');
});
return false;
});
$('a.read-less').click(function () {
$(this).parent('.content').slideUp('fast',function(){
$(this).closest('li').find('.excerpt').show();
$('ul').masonry('layout');
});
return false;
});
});
$('ul').masonry({
itemSelector: 'li',
});
JSFiddle: https://jsfiddle.net/yq7f1a63/2/

Slide Effects for Tabs Part 2

Ok so my original question got answered and now my slide effect only happens when I click in anywhere in my div region..here is the code:
$(document).ready(function(){
$('#tabs').tabs();
$("#tabs").click(function() {
$(this).effect( "slide", "medium" );
});
});
Now I'm wondering what if somebody wants to copy text from one of my tab regions? Every single time they try to highlight, the tab will slide away. How do I make it so that the tab region only slides when the actualy tab ul is clicked?
Use combination of mousedown and mouseup:
Demo Fiddle
var down=0;
$(document).ready(function(){
$("#tabs").mousedown(function(event){
down=event.clientX+"||"+event.clientY;
});
$("#tabs").mouseup(function(event){
var up=event.clientX+"||"+event.clientY;
if(up==down)
$(this).slideUp("medium" );
});
});
Updated code which prevent slidedown on right-click copy text:
Demo Fiddle 2
var down="||";
$(document).ready(function(){
$("#tabs").mousedown(function(event){
switch(event.which){
case 1:/*Left mouse button pressed*/
down=event.clientX+"||"+event.clientY;
break;
default:/*middle or right mouse button pressed*/
down="||";
}
});
$("#tabs").mouseup(function(event){
var up=event.clientX+"||"+event.clientY;
if(up==down)
$(this).slideUp("medium" );
});
});
You can use the event capturing option on click method. By using that, you can get the element on which the mouse is clicked. And then you can use the target object as below,
$('#tabs').click(function(e){
if(e.target.nodeName == 'P') {
e.stopPropagation();
return;
}
$(this).effect( "slide", "medium" );
});
Hope it will help.

jQuery toggle on dropdown

The problem:
In the example provided below, I have a sidenav with options, you click to reveal a toggled div. If you click the third item in the menu "Dolar", you will see you get a dropdown with three options appear below the link.
This is great, but I want the dropdown to close when I click on the other links. I'm not sure how to achieve this.
jsFiddle:
http://jsfiddle.net/visualdecree/4A23Z/39/
jQuery:
Note: I know it might be messy, I'm still learning this.
$('.sn a, .sn-alt a').on('click',function(){ // Sidenav panel script
var panID = $("#" + $(this).data('panel') );
$("div[id*='sn-pan-']")
.stop()
.hide({width:'toggle'},400);
$(panID)
.css({'left' : '139px','overflow':'visible'})
.stop()
.animate
({ width: "toggle", opacity: "toggle"
}, { duration: "slow" });
$(".control-view").hide(); // Fadein menu close button
$(".control-view").not(":visible").stop().delay(400).fadeTo("fast", 0.33);
});
$('.sn, .sn-drop').click(function(e) {
$('ul.sidenav li').not(this).removeClass('active'); // Active class removal / add
$(this).stop(true, true).toggleClass("active");
});
$('.sn-alt').click(function(e) {
$('ul.additional li').not(this).removeClass('active'); // Active class removal / add
$(this).stop(true, true).toggleClass("active");
});
$(".control-view").hover( // Hover effect for menu close button
function () {
$(".control-view").stop().hide().fadeTo("fast", 1); // Hover in
},
function () {
$(".control-view").fadeTo("normal",0.33); // Fade back to previous set opacity
});
$('.control-view').click(function(e) {
$("div[id*='sn-pan-']")
.stop(true,true)
.hide({width:'toggle'}, 100);
$('ul.sidenav li').not(this).removeClass('active');
$(".control-view").stop().fadeOut("fast");
});
$(".additional").hide(); // Controls for the 'design' dropdown
$(".sn-drop").click(function(){
$(".additional").slideToggle(300);
var scrt_var = Math.random();
return false; //Prevent the browser jump to the link anchor
});
Just add this JQuery, when you click on other link in your sidebar, it will close your .additional
$(".sn").click(function(){
$(".additional").slideUp(300);
var scrt_var = Math.random();
return false; //Prevent the browser jump to the link anchor
});
​
If it's just the links in the left that you want to be the trigger to close the dropdown then you can do it simply with this:
$('.sn').click(function(){
$('.additional').slideUp();
})

How check mouseover on two elements ?

I need hide tooltip on mouseout of link, BUT not if mouseover on tooltip (both have different parents)
For example: we can see it on Facebook when hover on names or avatars friends
I try this but every time i get FALSE
$('a').bind('mouseleave', function () {
var i = $('div.tooltip').is('hover');
if(i===true){
console.log('cursor over the tooltip, so dont hide');
}
else{
console.log('hide tooltip');
}
});
How i can check both condition?
Put both the link and the tool tip in the same parent:
<div id="parent">
link
<div id="tooltip">tooltip</div>
</div>
And then in the script you can just put the mouseleave function on the parent:
$("#parent a").mouseenter(function(){
$("#tooltip").css("display","block"); //or however you handle this
});
$("#parent").mouseleave(function(){
$("#tooltip").css("display","none");
});
If you can't change your markup, use a timed event and abort it when the mouse enter either element, like so:
var timer;
$("a, .tooltip").mouseleave(function() {
timer = setTimeout(doSomething, 10);
}).mouseenter(function() {
clearTimeout(timer);
});
function doSomething() {
console.log('hide tooltip');
}
Here's a FIDDLE

JQuery Fading Problem

I have a menu which has 8 pictures and I want to write a fade effect for them. I want to show the name of the menu when the mouse goes over it, and hide it when mouse goes out. Here is my code for two of my menu items:
$(".menu_account").mouseover(function(){
$("#menu_name").html('first');
$("#menu_name").fadeIn('slow', function(){
$(".menu_account").mouseout(function(){
$("#menu_name").fadeOut('slow', function(){});
})
});
});
$(".menu_myposts").mouseover(function(){
$("#menu_name").html('second');
$("#menu_name").fadeIn('slow', function(){
$(".menu_myposts").mouseout(function(){
$("#menu_name").fadeOut('slow', function(){});
})
});
});
My problem is when I am on the first item and the name has been appeared, when I move the cursor to the second item before the first fades out, the name's innerHTML changes and it gets ugly. I want to wait for fading out to be completed and start again. I really appreciate any help.
thanx.
Here is my full code:
HTML :
<div id="menu">
<a class="menu_account"></a>
<a class="menu_myposts"></a>
<a class="menu_allposts"></a>
<a class="menu_favorites"></a>
<a class="menu_follow"></a>
<a class="menu_logout"></a>
<a class="menu_help"></a>
<a class="menu_contact"></a>
</div>
<div style="height:20px;width:200px;margin:0 auto;text-align:center;">
<div id="menu_name" style="font-size:30px;color:#A1A1A1;display:none;"></div>
</div>
JS :
$("#menu").ready(function(){
$(".menu_myposts").hover(
function () {
$("#menu_name").html('first');
$("#menu_name").fadeIn('slow', function(){});
},
function () {
$("#menu_name").fadeOut('slow', function(){});
}
);
$(".menu_myposts").hover(
function () {
$("#menu_name").html('second');
$("#menu_name").fadeIn('slow', function(){});
},
function () {
$("#menu_name").fadeOut('slow', function(){});
}
);
});
Correct JS:
$(".menu_item").hover(
function() {
$("#menu_name").html($('#' + this.id + '_name').html());
$("#menu_name").stop(true, true).fadeIn();
},
function() {
$("#menu_name").stop(true, true).fadeOut();
}
);
I guess the mouseout event should be defined outside like this:-
$(".menu_account").mouseover(function(){
$("#menu_name").html('first');
$("#menu_name").fadeIn('slow', function(){
});
});
$(".menu_account").mouseout(function(){
$("#menu_name").fadeOut('slow', function(){});
})
That's why the fadeout happens immediately.
You could reuse the code like this :-
var menuClasses = {'menu_account' : 'first', 'menu_classes' :'second'};
$.each(menuClasses function(index, value) {
$("."+value).hover(dothisOnMouseover(value), dothisOnMouseout())
});
$("td").hover(
function () {
$(this).addClass("hover");
},
function () {
$(this).removeClass("hover");
}
);
function dothisOnMouseover(value)
{
$("#menu_name").html(value);
$("#menu_name").fadeIn('slow', function(){});
}
function dothisOnMouseout()
{
$("#menu_name").html('');
$("#menu_name").fadeOut('slow', function(){});
}
Updates
The solution is to somehow check inside dothisOnMouseout() if the fadeIn() has completed already. But I don't know how to do that. So, I have this other trick to enable mouseover only if fadeOut() is complete -
function dothisOnMouseover(value)
{
//Remove the `onmouseover="dothisOnMouseover()" binding of all other menus here - or may be all menus - check it.
$("#menu_name").html(value);
$("#menu_name").fadeIn('slow', function(){
//On completion of this fade in attach back the `onmouseover="dothisOnMouseover"` event binding all other menus here - Note - do not call `dothisOnMouseout()` here
});
}
Doing so, if you hover on any menu before the fadeOut() completes, nothing will happen. try it out.
I've created a Fiddle that might be interesting. It is similar to the one in this post with the difference that the names of the menu items are created on the fly.
The code from the fiddle:
$("#menu li").hover(
function() {
if (!$(this).data("name")) {
$(this).data("name",
$('<div class="name"></div>')
.text($(this).text())
.hide()
.appendTo("#nameWrapper"));
}
$(this).data("name")
.stop(true, true)
.fadeIn();
},
function() {
$(this).data("name")
.stop(true, true)
.fadeOut();
}
);
The idea is to have a name element for every menu item so you get a nice fade effect when the old name fades out and new one fades in at the same time.
The first part of the first hover function creates a name element if there isn't one. The element is connected with the menu item using the data() function.
The second part of the first hover function just fades in the name element. The second function fades it out.
The trick here is to use stop(true, true) to stop all animation on the element.
EDIT:
You start with a html structure like this one:
<ul id="menu">
<li>First</li>
<li>Second</li>
</ul>
<div id="nameWrapper"></div>
And after a couple of mouseover's over the menu items the nameWrapper div gets filled like so:
<div id="nameWrapper">
<div class="name">First</div>
<div class="name">Second</div>
</div>
The div.name elements is what actually gets shown when you hover over the menu items. The div.name elements are created when you hover over the menu item for the first time, in the folowing code section:
$(this).data("name", // associate the <div class="name"> element with the menu item that is currently hovered - $(this)
$('<div class="name"></div>') // create a div element
.text($(this).text()) // set text inside div to text of the menu item
.hide() // hide the div (it gets faded in later)
.appendTo("#nameWrapper")); // append the element to the element with id nameWrapper
Edit: See this jsFiddle code
I would bind all your menu items at once with a class name with an id attached to each one, like (I'm just guessing your HTML structure here):
<ul id="menu">
<li class="menu-item" id="account">Account</li>
<li class="menu-item" id="myposts">My Posts</li>
</ul>
And your javascript might be something like the below. Keep in mind that it's untested though, and I'm not sure what effect it would have on performance.
bindMouseOver();
$('.menu-item').mouseout(function(){
$('.menu-item').unbind('mouseover'); //disable all mouseovers while fadeOut is happening
$("#menu_name").fadeOut('slow', function(){
bindMouseOver(); //rebind the mouseover event after the fadeOut is completed
});
});
var bindMouseOver = function(){
$('.menu-item').mouseover(function(){
$("#menu_name").html($(this).html()); //use the menu item's innerHTML text, or something else if you prefer
$("#menu_name").fadeIn('slow');
});
};
Here is a JSFiddle I made that kind of simplifies all the JS into one hover listener: Example here
[EDIT] updated to auto load the menu title container...
Code to example:
CSS
#menu_name div{
position:absolute;
display:none;
}
.menu_link{
cursor:pointer;
}
HTML
<div id="menu_name"></div>
<br/>
<div id="menu_account" class="menu_link">link 1</div>
<div id="menu_myposts" class="menu_link">link 2</div>
JavaScript
(function() {
//auto-load the menu title container...
$(".menu_link").each(function(index, item) {
$('#menu_name').append('<div id="' + item.id + '-title">' + item.innerHTML + '</div>');
});
$(".menu_link").hover(
function() {
$('#' + this.id + '-title').fadeIn('medium');
}, function() {
$('#' + this.id + '-title').fadeOut('medium');
});
})();

Categories