jquery incomplete animation on hover - javascript

I am working on a navigation system for my site. The idea is to display the content when the parent is hovered.
But, when content is hovered fast, the animation is incomplete and it stops in between.
The complete working and code is in the demo link below. Any suggestions on the changing the code will be helpful.
DEMO: http://jsfiddle.net/vaakash/yH9GE/
When the "two" arrows are hovered at the same time (move fast from one
arrow to another) they stop and are incomplete
The code I used is
$('.anpn-wrap').mouseenter(function(){
$wrap = $(this);
$txt = $(this).find('.anpn-text');
$cnt = $(this).find('.anpn-cnt');
$txt.hide();
$cnt.css({ 'opacity': 0, 'margin-top': '-50px', 'width': '200px' });
$wrap.stop().animate({ 'width': $cnt.outerWidth() });
$cnt.show().animate({ 'opacity': 1, 'margin': 0});
});
$('.anpn-wrap').mouseleave(function(){
$wrap = $(this);
$txt = $(this).find('.anpn-text');
$cnt = $(this).find('.anpn-cnt');
$cnt.show().stop().animate({ 'opacity': 0, 'margin-top': '-50px' }, function(){
$cnt.hide();
$wrap.stop().animate({ 'width': $txt.outerWidth() });
$txt.fadeIn();
});
});​

By not localizing $wrap, $txt and $cnt, they will be global, hence if a mousenter event occurs before an earlier mouseleave animation has finished, these vars will be overwritten and the callbacks in the first animation will address the other button's elements.
The solution is to declare $wrap, $txt and $cnt with var, in both handlers.
Try this:
$('.anpn-wrap').mouseenter(function() {
var $wrap = $(this).stop();
var $txt = $wrap.find('.anpn-text').hide();
var $cnt = $wrap.find('.anpn-cnt').css({
'opacity': 0,
'margin-top': '-50px',
'width': '200px'
}).show().animate({
'opacity': 1,
'margin': 0
});
$wrap.animate({
'width': $cnt.outerWidth()
});
}).mouseleave(function() {
var $wrap = $(this);
var $txt = $wrap.find('.anpn-text');
var $cnt = $wrap.find('.anpn-cnt').show().stop().animate({
'opacity': 0,
'margin-top': '-50px'
}, function() {
$cnt.hide();
$wrap.stop().animate({
'width': $txt.outerWidth()
});
$txt.fadeIn();
});
});

I don’t know what you want instead, but you can pass arguments to stop() to force-complete the animation.
stop(true, true)
See this version: http://jsfiddle.net/yH9GE/2/

Related

GSAP Javascript if else statement woes

I'm building a basic online banking app with HTML, CSS, and JS.
So far I have the recent transaction screen and a simple animation for opening each individual transaction's description.
I used GSAP to create the animation, and jQuery for handling elements.
However, I have run into a problem getting the description window to close after it has been opened.
CODEPEN HERE, and here is the JS:
$(document).ready(function() {
$('.list li').click(function() {
var i = $(this).find('i');
var li = $(this);
var desc = $(this).next();
var tl = new TimelineMax({paused:false});
var open = false;
if (open === true) {
tl.to(i, .3, {rotation: 0})
.to(li, .3, {borderBottom: 'none', delay: -.2})
.to(desc, .3, {height: '0', padding: '0', delay: -.2});
open = false;
} else {
tl.to(i, .3, {rotation: 90})
.to(li, .3, {borderBottom: '2px solid #95a5a6', delay: -.2})
.to(desc, .3, {height: '55px', padding: '5px', delay: -.2});
open = true;
}
});
});
I use an if statement to decide which animation to play depending on if the description window is open or closed.
I am a designer learning to code, I will take any advice I can get.
You have the right idea, but var open = false; is in the wrong scope. The way it's written, open is defined as false every time the click handler is called, You want to put it in the parent scope: outside the click handler, before the click handler is ever called.
EDIT since you want to track the "open" state of each element, you need to create a closure for each element. You can do that using .each().
You can do this:
$(document).ready(function() {
$('.list li').each(function() {
var open = false; // <-- Put "open" here
$(this).click(function() {
var i = $(this).find('i');
var li = $(this);
var desc = $(this).next();
var tl = new TimelineMax({paused:false});
// get rid of "open" here
if (open === true) {
tl.to(i, .3, {rotation: 0})
.to(li, .3, {borderBottom: 'none', delay: -.2})
.to(desc, .3, {height: '0', padding: '0', delay: -.2});
open = false;
} else {
tl.to(i, .3, {rotation: 90})
.to(li, .3, {borderBottom: '2px solid #95a5a6', delay: -.2})
.to(desc, .3, {height: '55px', padding: '5px', delay: -.2});
open = true;
}
});
});
});

Disable mouseover until animation complete

I use jquery caroufredsel to create a slider, and then attach mouseover event to the items so that when mouse over the item it will center the selected one. here is the script
$(document).ready(function(){
$('#carousel-popular').carouFredSel({
width: '100%',
items: 5,
scroll: 1,
auto: false,
prev: '#prev-popular',
next: '#next-popular',
pagination: '#pager'
});
$('#carousel-popular img').off('mouseover').on('mouseover', function(){
var self = this;
$(this).attr('data-url', '<?php echo site_url('video/video_display'); ?>/'+$(this).data('vid'));
$('#carousel-popular').trigger('slideTo', [$(this), -2]);
$('#home-sidebar').load('<?php echo site_url('home/get_imdb');?>/'+$(this).data('vid'), function(){
$('#carousel-popular img').removeClass('selected');
$(self).addClass('selected');
});
// $('.caroufredsel_wrapper').css({
// "background" : "url(<?php echo base_url(); ?>images/shadow.png) center 95% no-repeat"
// });
});
$('#carousel-popular img').on('click', function(){
if($(this).hasClass('selected')){
window.location = $(this).data('url');
}
})
var sbHeight = $('body').height() - $('#header').height();
$('#home-sidebar').css({
"height": sbHeight+'px'
});
setTimeout(function(){
$('#carousel-popular img').eq(0).trigger('mouseover');
}, 500);
});
The problem is when an item is sliding to center another images catch the mouseover because the mouse pointer is still on the track. How to disable this mouseover event untill the selected image is centered?
fiddle
I'm not entirely sure of the issue, but you could try this:
$('#carousel a').on('mouseenter', function(){
$('#carousel').trigger('slideTo', [$(this), -2]);
});
That triggers the animation when the mouse moves over the element
pretty unclear question to me, is this what you want: http://jsfiddle.net/8W25g/2/
$('#carousel').carouFredSel({
items: 4,
scroll: 1,
auto: false,
prev: '#prev-popular',
next: '#next-popular',
pagination: '#pager'
});
var mouseoverFunc=function(){
$('#carousel a').unbind('mouseover');
$('#carousel').trigger('slideTo', [$(this), -2]);
};
var mouseoutFunc=function(){
setTimeout(function(){
$('#carousel a').bind('mouseover',mouseoverFunc);
},400);
};
$('#carousel a').bind('mouseover', mouseoverFunc);
$('#carousel a').bind('mouseout', mouseoutFunc);

how to animate height of a div back-jquery

I'm trying to show some part of a div and animate it to 100% when the div is clicked.
and I want to animate it back to the initial height of the div if it's clicked again.
this is what i have so far,but it doesn't work. can anyone help?
#mydiv {
height:150px;
width: 100%;
overflow:hidden;
}
<script type="text/javascript">
$(document).ready(function(){
$("#mydiv").click(function(){
$(this).animate({height: '100%'}, 300);
}, function() {
$(this).animate({height: '150px'}, 300);
});
});
</script>
click() doesn't accept two function arguments, previously there was a toggle() function that performed how you need it but it has now been deprecated and removed from jQuery.
Since your use case is pretty simple, I believe something like this would be enough:
$("#mydiv").click(function () {
var $this = $(this);
$this.animate({
height: $this.height() == 150 ? '100%' : 150
}, 300);
});
Demo fiddle
This should do the job for you.
jQuery:
$(document).ready(function() {
$("#mydiv").toggle(
function() {
$(this).animate({height: '100%'}, 300);
};
function() {
$(this).animate({height: 150}, 300);
});
});

How to safely fire two open handlers jQuery

Some of my pages work, some of them don't. The ones that don't work are the ones with a custom event handler. All pages have the following jQuery code.
var speed = 750;
$(document).on("dialogopen", ".dialogClass", function() {
var parent = $(this).parent();
$(this).dialog("option", "width", $(window).width());
$(this).dialog("option", "height", $(window).height());
$(this).dialog("option", "position", [0,0]);
$(this).dialog("option", "draggable", "false");
parent.css("position","fixed");
parent.css("top","0px");
parent.css('left','-' + $(window).width() + 'px');
parent.animate({
left: 0
}, speed, "easeOutBounce");
});
$(document).on("dialogclose", ".dialogClass", function() {
if($('#dialog').is(':data(dialog)')){
$(this).dialog("destroy");
$(this).swipe("destroy");
$(this).swipe({
swipeLeft:function(event, direction, distance, duration, fingerCount) {
if(distance >= 200){
var dia = $(this);
$(this).parent().animate({
left : -$(window).width()
},speed, "easeInExpo", function(e) {
dia.dialog("close");
});
}
}
});
}
});
Some dialogs have custom open\close handlers such as (theDialog is of class dialogClass):
$("#theDialog").dialog({
width: 700,
height:675,
title:'Add Event',
resizable:false,
modal:true,
close: function(event,ui{
$("#theDialog").html('');
//Do other things
});
Is it proper jQuery to have two close handlers? Are these conflicting in any way shape or form? If so how can I have the custom event handler fire as well as the global class one.

Right click keeps propagating in Firefox

I just noticed something unusual. This is what I want to accomplish:
I want a div to be shown when I click a link
I want the div to disappear when I click somewhere else in the document
I don't want it to disappear when I click the div itself
Something like this:
http://jsfiddle.net/XPmyF/
JS:
(function() {
var box = $('#box');
$(document).on('click', function() {
if (box.css('display') == 'block') {
box.css('display', 'none');
}
});
$('#start').on('click', function(e) {
box.css({
'text': 'Box',
'position': 'absolute',
'top': '50px',
'left': '0',
'background': '#EEE',
'border': '1px solid #555',
'width': '200px',
'height': '50px',
'display': 'block'
});
e.stopPropagation();
});
box.on('click', function(e) {
e.stopPropagation();
});
})();​
That fiddle works just fine but when I tested that in Firefox (15.0.1), if you right-click on the div, it dissapears, which is not the behavior I'm looking for. It seems that stopPropagation() works for clicks but not right-clicks in Firefox. Chrome keeps right-clicks from propagating to the document.
How can I fix it?
Thanks
Use the event.which method to detect which button was clicked. Here's an example in jsfiddle.
$(document).on('click', function(event) {
if (event.which == 1 && box.css('display') == 'block') {
box.css('display', 'none');
}
});
Edited to actually work...
Sorry about that, the events didn't work as anticipated. You could handle it with mouse-overs.
(function() {
var box = $('#box');
var clicky = true;
$(document).on('click', function() {
if (box.css('display') == 'block' && clicky) {
box.css('display', 'none');
}
});
$('#start').on('click', function(e) {
box.css({
'text': 'Box',
'position': 'absolute',
'top': '50px',
'left': '0',
'background': '#EEE',
'border': '1px solid #555',
'width': '200px',
'height': '50px',
'display': 'block'
});
e.stopPropagation();
});
box.mouseenter(function(e) {
clicky = false;
});
box.mouseout(function(e) {
clicky = true;
});
})();

Categories

Resources