jquery, hover over parent, slideToggle child, not work quite well - javascript

So when user hover over div(#cart-quick-view) child(.cart_details_box) needs to slideDown, and to slideUp when mouse gets out of parent(#cart-quick-view). Problem with this code is that sometimes I get 2-3 extra bouncing when mouse is in area of child(.cart_details_box).
Fiddle: http://jsfiddle.net/Y9QLC/
HTML:
<div id="cart-quick-view">
<ul class="nav navbar-nav navbar-right">
<li>...</li>
</ul>
<div class="cart_details_box"></div>
</div>
CSS:
#cart-quick-view {
float: right;
position: relative;
border: 1px solid black;
}
.cart_details_box {
display: none;
position: absolute;
height: 200px;
width: 205px;
background-color: #F8F8F8;
border-radius: 5px;
border:1px solid #E7E7E7;
padding: 0px 3px 3px 3px;
top: 55px;
right: 0;
}
JS:
$(function() {
$('#cart-quick-view').hover(function() {
$('.cart_details_box').slideToggle('slow');
});
});

It is because of the queuing of animations when the mouse enter and leave the parent element quickly. You can use .stop(true, true) to clear the existing animations to fix it
$(function () {
$('#cart-quick-view').hover(function () {
$('.cart_details_box').stop(true, true).slideToggle('slow');
});
});
Demo: Fiddle

The stop() method is an option, but there is also a jQuery plugin available called hoverFlow that can fix the problem with a better looking transition.

Related

On hover slide image left (jQuery) and back if no hover

First, thanks for reading my question. I'm trying to make grid of 3 images that slide over each other when a user hovers over it. I've seen this on many websites but I don't know what this effect/plugin is called. So I made a image and a fiddle of what I'm trying to accomplish.
The start:
3 images positioned horizontally. The first image is almost completely visible except for some tab-like bars on the right. When you would hover over the second image it will slide to the left leaving only a small (again) tab-like bar on the right. The same goes for the third image. See this image I've made.
If a user doesn't hover any of the images it just goes back to the default of showing the first image and the second and third image in tab-like state.
I've also made a fiddle here to show the way the images should be animated.
But as you can see this is not perfect. Does anyone here have a snippet I could use because my jQuery skills are not there yet. But I think this (should) could be accomplished easier and with less code I think? And even maybe more elegantly.
Thanks for the (long) read...
This is simple example ;]
$('li').hover(function() {
$(this).addClass('active');
}, function(){
$(this).removeClass('active');
})
li {
width: 0;
padding: 15px;
float: right;
height: 300px;
overflow: hidden;
cursor: pointer;
color: #fff;
}
li:nth-child(1) {
background: red;
}
li:nth-child(2) {
background: green;
}
li:nth-child(3) {
background: blue;
}
li.active {
width: 400px;
transition: all 1s;
}
ul {
list-style: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>page 1</li>
<li>page 2</li>
<li>page 3</li>
</ul>
Try zAccordian jquery plugin. https://natearmagost.github.io/zaccordion/index.html
So I changed your example a bit:
What I did was:
Changed positions to relative and set overflow hidden to .wrapper
$(document).ready(function(){
$(".img-1").hover(function(){
$('.img-2').stop().animate({'left': '160px'}, 500);
$('.img-3').stop().animate({'left': '180px'}, 500);
}, function(){
$('.img-2').stop().animate({'left': '160px'}, 500);
$('.img-3').stop().animate({'left': '180px'}, 500);
});
$(".img-2").hover(function(){
$('.img-2').stop().animate({'left': '20px'}, 500);
}, function(){
$('.img-2').stop().animate({'left': '160px'}, 500);
});
$(".img-3").hover(function(){
$('.img-2').stop().animate({'left': '20px'}, 500);
$('.img-3').stop().animate({'left': '40px'}, 500);
}, function(){
$('.img-3').stop().animate({'left': '180px'}, 500);
$('.img-2').stop().animate({'left': '160px'}, 500);
});
});
.img-1 {position:relative;top:0px; background-color:red; width: 200px; Height: 50px;}
.img-2 {position:relative;top:-50px;left:160px; background-color: #1F6; width: 200px; Height: 50px;}
.img-3 {position:relative;top:-100px;left:180px; background-color: #0FF; width: 200px; Height: 50px;}
.wrapper {
border: black 1px solid;
width: 200px;
Height: 50px;
position:relative;
overflow: hidden;
top:0px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="img-1">
</div>
<div class="img-2">
</div>
<div class="img-3">
</div>
</div>
You can do this completely with CSS, no need for javascript.
The example below manipulates the z-index when a div is hovered. The only tricky one is the hover of 'image-3'. The z-index of 'image-2' needs to be changed also to ensure it is on top of 'image-1'.
Therefore, in the HTML 'image-2' is placed after 'image-3'. Than in CSS 'image-2' can be addressed as a sibling.
[class^="img"] {
position: absolute;
top: 0;
left: 0;
}
.img-1 {
z-index: 3;
}
.img-1 img {
border: 6px solid #FF0;
}
.img-2 {
left: 20px;
z-index: 2;
}
.img-2 img {
border: 6px solid #F00;
}
.img-3 {
left: 40px;
z-index: 1;
}
.img-3 img {
border: 6px solid #F60;
}
div[class^="img"]:hover {
z-index: 5;
}
.img-3:hover+.img-2 {
z-index: 4;
}
<div class="wrapper">
<div class="img-1">
<img src="//placehold.it/200x50&text='image-1'" alt="">
</div>
<div class="img-3">
<img src="//placehold.it/200x50&text='image-3'" alt="">
</div>
<div class="img-2">
<img src="//placehold.it/200x50&text='image-2'" alt="">
</div>
</div>

JavaScript Event Firing Twice

I have a short piece of JS which is supposed to show and hide the secondary navigation of a site. If a user clicks Menu Item A it shall show, they click it again and it hides and if Menu Item A is open and they click Menu Item B then it closes A and opens B in its place.
The first part of this works, I can click a single menu item and it will open and close, if however I click a different menu item whilst one is open then it shall close (as expected), open (as expected) and then close again. It's as if the event is being fired twice.
Here is my JS snippet.
$(document).ready(function() {
$('.NavButton').click(function(event) {
handleSecondaryNavigation(event.target.alt);
});
});
function handleSecondaryNavigation(MenuItem) {
if ($('#ul' + MenuItem).is(':visible')) {
// Menu item visible, hide it
$('#SecondaryNavigation').animate({
width: 'toggle'
}, 350, function() {
$('#ul' + MenuItem).hide();
});
} else if ($('#SecondaryNavigation').is(':visible')) {
// Clicked different menu item, hide then show (swap)
$('#SecondaryNavigation').animate({
width: 'toggle'
}, 350, function() {
$('#SecondaryNavigation ul').hide(function() {
handleSecondaryNavigation(MenuItem);
});
});
} else {
// Menu not visible, show it
$('#ul' + MenuItem).show(function() {
$('#SecondaryNavigation').animate({
width: 'toggle'
}, 350);
});
}
}
#MainNavigation {
background: #F1F1F1;
position: fixed;
top: 0px;
left: 0px;
bottom: 0px;
}
#MainNavigation .NavButton {
width: 20px;
display: block;
padding: 15px 20px;
cursor: pointer;
}
#SecondaryNavigation {
position: fixed;
top: 0px;
left: 60px;
bottom: 0px;
background: #DADADA;
width: 200px;
display: none;
box-shadow: 2px 0px 5px #686868;
}
#SecondaryNavigation ul {
display: none;
margin: 0px 10px;
}
#SecondaryNavigation ul li {
display: block;
padding: 10px;
border-bottom: 1px solid #CBCBCB;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="MainNavigation">
<img class="NavButton" alt="A" />
<img class="NavButton" alt="B" />
</nav>
<nav id="SecondaryNavigation">
<ul id="ulA">
<li>Lorem</li>
<li>Ipsum</li>
</ul>
<ul id="ulB">
<li>Lorem</li>
<li>Ipsum</li>
</ul>
</nav>
Swapping out the handleSecondaryNavigation(MenuItem) bit and hard coding the action installed of recursively also does not work.
Any ideas? I'm sure it's probably something silly...
Thanks
I have solved your issue and please find the working fiddle
This event listener is triggered twice each time for each ul element
$('#SecondaryNavigation ul').hide(function() {
console.log("hide trug");
handleSecondaryNavigation(MenuItem);
});
change this to
$('#SecondaryNavigation ul').hide(function() {
});
handleSecondaryNavigation(MenuItem);
I have updated the fiddle as well
Hope this helps

Change color of div when hovering over li

I have a stack of li's. I'm trying to get the background color of a div to change upon mouse on and change back upon mouse off. I was able to figure out how to do it, but it's buggy. The gaps between the li's cause an issue where the jquery isn't triggered correctly when I hover from one li to another.
Here's my code: http://jsfiddle.net/blutuu/k93o28rf/8/
It's quite hacky, so I'm hoping for a better implementation. Thanks for your help.
I'm stacking on top of both answers above. I did a little rearranging of the code and I think I finally got what you are looking for. I tucked the <li> tag inside of the <a> tags, at which point the entire element even when a border is added became clicable.
$(document).ready(function() {
$('li').mouseenter(function() {
var color = $(this).data('color');
$('#mbg').css('background-color', color);
});
$('li').mouseout(function() {
$('#mbg').css('background-color', 'blue');
});
});
.resources {
width: 17%;
height: 100vh;
overflow: hidden;
position: absolute;
z-index: 1;
border-right: solid 1px #C5C5C5;
box-shadow: 2px 0px 2px -1px #DCDCDC;
}
.resources ul {
text-align: right;
padding: 0;
margin: auto 0;
}
.resources ul > li a {
list-style-type: none;
height: 65px;
background: #00ADEF;
border-bottom: solid #0088BC 1px;
vertical-align: middle;
overflow: hidden;
padding: 0;
box-shadow: 0px -1px 5px -2px #222 inset;
box-sizing: border-box;
transition: .5s;
}
.resources ul li a:hover {
border-right: 25px solid #8CC63E;
vertical-align: middle;
overflow: hidden;
/*transition: .5s;*/
}
.resources li a {
line-height: 1em;
text-decoration: none;
color: white;
font-size: 20px;
font-weight: bold;
display: block;
padding: 1.13em;
}
#mbg {
position: absolute;
background-color: blue;
width: 100%;
height: 100vh;
margin-left: 17%;
}
#layoutsTable {
border: solid 1px #f08721;
height: 100vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="mbody">
<div class="resources">
<ul>
<a href="#">
<li data-color="#380606">Policies</a>
</li>
<a href="#">
<li data-color="#191919">LMS</a>
</li>
<a href="#">
<li data-color="#cbcbcb">Tips & Tricks</a>
</li>
<li data-color="#f08721">Forms
</li>
</ul>
</div>
<div id="mbg"></div>
</div>
Demo: http://jsfiddle.net/k93o28rf/6/
Use of bind to pass params directly to the changeColor function.
Define a changeColor function so you don't have to define costly vars everytime.
And simply call .css function on your div id to set background-color.
$(document).ready(function() {
var content = $('#mbg');
var changeColor = function(color) {
content.css('background-color', color);
}
$('li').eq(0).hover(
changeColor.bind(null, '#380606')
);
$('li').eq(1).hover(
changeColor.bind(null, '#191919')
);
$('li').eq(2).hover(
changeColor.bind(null, '#191919')
);
$('li').eq(3).hover(
changeColor.bind(null, '#f08721')
);
$('li').mouseout(
changeColor.bind(null, 'blue')
);
});
demo: http://jsfiddle.net/k93o28rf/3/
by using data tag attributes on each of the li elements, you can just have one mouseenter function and one mouseout function to handle the background color changes as shown below.
<div id="mbody">
<div class="resources">
<ul>
<li data-color="#380606">Policies</li>
<li data-color="#191919">LMS</li>
<li data-color="#cbcbcb">Tips & Tricks</li>
<li data-color="#f08721">Forms</li>
</ul>
</div>
<div id="mbg"></div>
</div>
$(document).ready(function() {
$('li').mouseenter(function() {
var color = $(this).data('color');
$('#mbg').css('background-color', color);
});
$('li').mouseout(function() {
$('#mbg').css('background-color', 'blue');
});
});
UPDATE:
Try using linear-gradient instead of border-right on your a elements:
http://jsfiddle.net/em96edb0/
The problem is the border you've applied to the bottom. Add this to your a element in CSS:
box-sizing:conteny-box;
And that should fix it. Also, to be more efficient, use JQuery's .each function. Something like this:
$('li').each( ///your code );

Sliding menu works fine but does double animations

I have just succeeded to make a menu that comes sliding in from the top with the help of Jquery. When I press the tab 'menu' it comes in/down and when I leave the menu, it slides back.
The problem is that when I press the menu tab quickly 2 times, it goes down the double amount of pixels.
Also when I leave the menu it goes up, but when I while the animation is still happening go back in and leave again, it also goes up the double amount of pixels.
This is my code:
CSS
#menu {
position:absolute;
left:0px;
top:-203px;
width: 100%;
z-index:1;
}
#menucontentwrapper {
background-color: #330066;
width: 100%;
height: 200px;
border-left: 3px solid #000000;
border-right: 3px solid #000000;
border-bottom: 3px solid #000000;
}
#menucontent {
height: 200px;
width: 820px;
margin: 0 auto;
}
#menutabwrapper {
width: 820px;
height: 50px;
margin: 0 auto;
}
#menutab {
background-color: #330066;
height: 30px;
width: 100px;
float: right;
border-bottom-left-radius: 10px;
-webkit-border-bottom-left-radius: 10px;
-moz-border-radius-bottomleft: 10px;
border-bottom-right-radius: 10px;
-webkit-border-bottom-right-radius: 10px;
-moz-border-radius-bottomright: 10px;
border-left: 3px solid #000000;
border-right: 3px solid #000000;
border-bottom: 3px solid #000000;
text-align: center;
vertical-align: middle;
line-height: 30px;
font-weight: bold;
font-size: 20px;
color: #FFFFFF;
}
The body
<div id="menu">
<div id="menucontentwrapper">
<div id="menucontent"></div>
</div>
<div id="menutabwrapper">
<div id="menutab">MENU</div>
</div>
</div>
<script>
$('#menutab').click(function() {
$('#menu').animate({
top: '+=203',
}, 1000, function() {
// Animation complete.
});
})
$('#menucontentwrapper').mouseleave(function() {
$('#menu').animate({
top: '-=203',
}, 500, function() {
// Animation complete.
});
})
</script>
Do any of you know a solution to this?
Thanks in advance!
You can do this way:
var $menutab = $('#menutab');
var $menu = $('#menu');
$menutab.one('click', slideDown);//Initially register one click event to slideDown
function slideDown()
{
$menu.animate({
top: '+=203',
}, 1000, function () {
$('#menucontentwrapper').one('mouseleave', slideUp);// On completion of animation register one mouseleave event to slideUp
});
}
function slideUp()
{
$menu.animate({
top: '-=203',
}, 1000, function () {
$menutab.one('click', slideDown);// On completion of animation register one click event to slideDown
});
}
Fiddle
The method works because by using one instead of on to attach the event handler, it makes it so neither event is handled while the animation is running. This is because a handler attached by one only executes once and is then removed. After the animation is complete the appropriate handler is attached in the complete callback of the animate function.
See .one()
Check out jQuery stop() method.
Before you call your animate functions, call stop. Using the parameters true, true will cause all of #menu's running animation to jump to the end. On the off chance you'll have multiple animations intentionally running, then you should check out how to use the queue parameter.
$('#menutab').click(function() {
$('#menu').stop(true, true).animate({
top: '0px',
}, 1000, function() {
// Animation complete.
});
})
$('#menucontentwrapper').mouseleave(function() {
$('#menu').stop(true, true).animate({
top: '-203px',
}, 500, function() {
// Animation complete.
});
})
You'll want to run a check to see if the element is in the middle of an animation on your click function:
$('#menutab').click(function() {
if( !$('#menu').is(':animated') ) {
$('#menu').animate({
top: '+=203',
}, 1000, function() {
// Animation complete.
});
}
})

Change 'Click' function to mouseover/mouseout

I am using the following sliding div script:
http://www.webdesignerwall.com/demo/jquery/simple-slide-panel.html
Currently, the slidetoggle function is activated when the .btn-slide button is clicked. This slides up the "panel" div.
Upon clicking the .btn-slide button a second time, the panel div is closed.
I am a complete newb at js, so any assistance would be appreciated. Here's what I am trying to do:
1) When the mouse moves over (as opposed to clicking) the .btn-slide class, i would like the panel to slide out.
2) Then, when the mouse moves out of either the .btn-slide or #panel, i would like the panel to close. (but if the mouse is over either one, the panel should stay open).
I was able to get it working to where the slidetoggle function would close either one, or the other, but not both.
Thank you in advance for the help.
Sincerely,
Mac
Here is the JS:
<script type="text/javascript">
jQuery(function($){
$(document).ready(function(){
$('.btn-slide').click(function() {
$("#panel").slideToggle("slow");
$(this).toggleClass("active"); return false;
});
});
});
</script>
here is the HTML currently being used:
<div id="prod_nav_tab">
<div id="panel">
This is where stuff goes!
</div>
<p class="slide"><a class="btn-slide">Table of Contents</a></p>
</div>
I have played with the CSS to fit my particular web site and is as follows (the original js, html, css can be obtained from the link above).
div#prod_nav_tab {
width: 200px;
height: 31px;
overflow: hidden;
background-color:#F00;
float: left;
margin: 0px 0px 0px 75px;
}
a:focus {
outline: none;
}
#panel {
background-color:#F00;
width: 200px;
height: 200px;
display: none;
position: absolute;
bottom: 0px;
}
.slide {
margin: 0;
padding: 0;
/* border-top: solid 4px #422410; **Adds a line at top of slide button to distibuish it */
background: url(images/btn-slide.gif) no-repeat center top;
}
.btn-slide {
background: #d8d8d8;
text-align: center;
width: 200px;
height: 31px;
padding: 0px 0px 0 0;
margin: 0 0 0 0;
display: block;
font: bold 12pt Arial, Helvetica, sans-serif;
color: #666;
text-decoration: none;
position: relative;
cursor: pointer;
/* background: url(images/white-arrow.gif) no-repeat right -50px; ** Controls Arrow up/down */
}
.active {
background-position: right 12px;
}
When you move away from the .btn-slide to the #panel it hides it now because it triggers the mouseleave event of the .btn-slide.
To prevent this you should do something like:
HTML:
<div id="trigger">
Slide down
<div id="panel">
Content of your panel
</div>
</div>
JQuery:
jQuery(function($) {
$(document).ready(function() {
$("#trigger").mouseenter(function() {
$("#panel").slideDown("slow");
$(this).addClass("active");
}).mouseleave(function() {
$("#panel").slideUp("slow");
$(this).removeClass("active");
});
});
});
Make sure in your CSS you then set the panel to be hidden from start...
div#panel {
display: none;
}

Categories

Resources